1 package info.ejava.examples.ejb.ejbjpa.dao;
2
3 import info.ejava.examples.ejb.ejbjpa.bo.Floor;
4 import info.ejava.examples.ejb.ejbjpa.bo.Guest;
5 import info.ejava.examples.ejb.ejbjpa.bo.Room;
6
7 import java.util.List;
8
9 import javax.persistence.EntityManager;
10 import javax.persistence.LockModeType;
11 import javax.persistence.TypedQuery;
12 import javax.persistence.criteria.CriteriaBuilder;
13 import javax.persistence.criteria.CriteriaQuery;
14 import javax.persistence.criteria.Expression;
15 import javax.persistence.criteria.Predicate;
16 import javax.persistence.criteria.Root;
17
18 public class JPAHotelDAO implements HotelDAO {
19 private EntityManager em;
20
21 public void setEntityManager(EntityManager em) {
22 this.em = em;
23 }
24
25 private <T> TypedQuery<T> withPaging(TypedQuery<T> query, int offset, int limit) {
26 if (offset > 0) {
27 query.setFirstResult(offset);
28 }
29 if (limit > 0) {
30 query.setMaxResults(limit);
31 }
32 return query;
33 }
34
35 @Override
36 public void populate() {
37 int roomCount=0;
38 for (int f=0; f<3; f++) {
39 Floor floor = new Floor(f);
40 for (int r=0; r<3; r++) {
41 Room room = new Room(floor, f*100 + r);
42 floor.withRoom(room);
43 if (roomCount++ % 2==0) {
44 Guest guest = new Guest("guest " + roomCount);
45 em.persist(guest);
46 room.setOccupant(guest);
47 }
48 }
49 em.persist(floor);
50 }
51 }
52
53 @Override
54 public void clearAll() {
55 em.createQuery("update Room r set r.occupant=null").executeUpdate();
56 em.createQuery("delete from Room").executeUpdate();
57 em.createQuery("delete from Floor").executeUpdate();
58 em.createQuery("delete from Guest").executeUpdate();
59 }
60
61 @Override
62 public void addFloor(Floor floor) {
63 em.persist(floor);
64 }
65
66 @Override
67 public Floor getFloor(int level) {
68 return em.find(Floor.class, level);
69 }
70
71 @Override
72 public Floor fetchFloor(int level) {
73 List<Floor> floors = em.createNamedQuery("Floor.fetchFloor",
74 Floor.class)
75 .setParameter("level", level)
76 .getResultList();
77 return floors.isEmpty() ? null : floors.get(0);
78 }
79
80 @Override
81 public List<Floor> getFloors(int offset, int limit) {
82 return withPaging(em.createNamedQuery("Floor.getFloors",
83 Floor.class),
84 offset, limit)
85 .getResultList();
86 }
87
88 @Override
89 public Room getRoom(int number) {
90 return em.find(Room.class, number);
91 }
92
93 protected TypedQuery<Room> getAvailableRoomsQuery(Integer level, int offset, int limit) {
94 CriteriaBuilder cb = em.getCriteriaBuilder();
95 CriteriaQuery<Room> qdef = cb.createQuery(Room.class);
96 Root<Room> r = qdef.from(Room.class);
97
98 Predicate pred = cb.conjunction();
99 List<Expression<Boolean>> expr = pred.getExpressions();
100 expr.add(cb.isNull(r.get("occupant")));
101 if (level!=null) {
102 expr.add(cb.equal(r.get("floor").get("level"), level));
103 }
104
105 qdef.select(r).where(pred).orderBy(cb.asc(r.get("number")));
106 return withPaging(em.createQuery(qdef),
107 offset, limit);
108 }
109
110 @Override
111 public List<Room> getAvailableRooms(Integer level, int offset, int limit) {
112 return getAvailableRoomsQuery(level, offset, limit)
113 .getResultList();
114 }
115
116 @Override
117 public List<Room> getAvailableRoomsForUpdate(Integer level, int offset, int limit) {
118 return getAvailableRoomsQuery(level, offset, limit)
119 .setLockMode(LockModeType.PESSIMISTIC_WRITE)
120 .setHint("javax.persistence.lock.timeout", 5000)
121 .getResultList();
122 }
123
124
125 @Override
126 public Room findRoomByGuest(Guest guest) {
127 List<Room> rooms = em.createNamedQuery("Room.findRoomByGuest",
128 Room.class)
129 .setParameter("guest", guest)
130 .getResultList();
131 return rooms.isEmpty() ? null : rooms.get(0);
132 }
133
134 @Override
135 public void addGuest(Guest guest) {
136 em.persist(guest);
137 }
138
139 }