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 }