JPAHotelDAO.java
package info.ejava.examples.ejb.ejbjpa.dao;
import info.ejava.examples.ejb.ejbjpa.bo.Floor;
import info.ejava.examples.ejb.ejbjpa.bo.Guest;
import info.ejava.examples.ejb.ejbjpa.bo.Room;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
public class JPAHotelDAO implements HotelDAO {
private EntityManager em;
public void setEntityManager(EntityManager em) {
this.em = em;
}
private <T> TypedQuery<T> withPaging(TypedQuery<T> query, int offset, int limit) {
if (offset > 0) {
query.setFirstResult(offset);
}
if (limit > 0) {
query.setMaxResults(limit);
}
return query;
}
@Override
public void populate() {
int roomCount=0;
for (int f=0; f<3; f++) {
Floor floor = new Floor(f);
for (int r=0; r<3; r++) {
Room room = new Room(floor, f*100 + r);
floor.withRoom(room);
if (roomCount++ % 2==0) {
Guest guest = new Guest("guest " + roomCount);
em.persist(guest);
room.setOccupant(guest);
}
}
em.persist(floor);
}
}
@Override
public void clearAll() {
em.createQuery("update Room r set r.occupant=null").executeUpdate();
em.createQuery("delete from Room").executeUpdate();
em.createQuery("delete from Floor").executeUpdate();
em.createQuery("delete from Guest").executeUpdate();
}
@Override
public void addFloor(Floor floor) {
em.persist(floor);
}
@Override
public Floor getFloor(int level) {
return em.find(Floor.class, level);
}
@Override
public Floor fetchFloor(int level) {
List<Floor> floors = em.createNamedQuery("Floor.fetchFloor",
Floor.class)
.setParameter("level", level)
.getResultList();
return floors.isEmpty() ? null : floors.get(0);
}
@Override
public List<Floor> getFloors(int offset, int limit) {
return withPaging(em.createNamedQuery("Floor.getFloors",
Floor.class),
offset, limit)
.getResultList();
}
@Override
public Room getRoom(int number) {
return em.find(Room.class, number);
}
protected TypedQuery<Room> getAvailableRoomsQuery(Integer level, int offset, int limit) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Room> qdef = cb.createQuery(Room.class);
Root<Room> r = qdef.from(Room.class);
Predicate pred = cb.conjunction();
List<Expression<Boolean>> expr = pred.getExpressions();
expr.add(cb.isNull(r.get("occupant")));
if (level!=null) {
expr.add(cb.equal(r.get("floor").get("level"), level));
}
qdef.select(r).where(pred).orderBy(cb.asc(r.get("number")));
return withPaging(em.createQuery(qdef),
offset, limit);
}
@Override
public List<Room> getAvailableRooms(Integer level, int offset, int limit) {
return getAvailableRoomsQuery(level, offset, limit)
.getResultList();
}
@Override
public List<Room> getAvailableRoomsForUpdate(Integer level, int offset, int limit) {
return getAvailableRoomsQuery(level, offset, limit)
.setLockMode(LockModeType.PESSIMISTIC_WRITE)
.setHint("javax.persistence.lock.timeout", 5000)
.getResultList();
}
@Override
public Room findRoomByGuest(Guest guest) {
List<Room> rooms = em.createNamedQuery("Room.findRoomByGuest",
Room.class)
.setParameter("guest", guest)
.getResultList();
return rooms.isEmpty() ? null : rooms.get(0);
}
@Override
public void addGuest(Guest guest) {
em.persist(guest);
}
}