View Javadoc
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 }