Saving and retrieving records in two related tabls wiht JPA

51 Views Asked by At

In my application there are two models with @onetomany realationship. I have defined Room and Seat entities. My first problem is that seats collection always returns null.


@Entity
public class Room implements Serializable {   
   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   private Long Id;
   private String name;
   @OneToMany(mappedBy = "room")
   Set<Seat> seats = new HashSet();

   protected Room() {

   }

   public void addSeat(Seat seat) {
      seat.setAssociatedRoom(this);
      seats.add(seat);
   }

   public Room(String name) {
      this.name = name;
   }

   public String getName() {
      return this.name;
   }

   public String getSeatsToString() {
      String out = "seats:";

      if(seats != null)
         for (Seat seat : seats)
            out += seat.getName()+ " ";
      return out;
        }
}


@Entity
public class Seat implements Serializable {

   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   private Long id;
   private String name;

   @ManyToOne       
   @JoinColumn(name = "roomId")        
   private Room room;

   protected Seat() {

   }

   public Seat(String name) {
      this.name = name;      
   }

   public String getName() {
      return this.name;
   }

   public void setAssociatedRoom(Room room) {
      this.room = room;    
   }    
}


This is the code used in database operations. I also need help with implementing search queries like "getSeatsByRoom(String room)".


@Component
public class SeatServiceImpl implements SeatService {

    @PersistenceContext private EntityManager em;

    @Transactional
    public void persist(Seat seat) {
        em.persist(seat);
    }

    public List<Seat getAllSeats() {
       TypedQuery<Seat> query = em.createQuery(
            "SELECT c FROM Seat c", Seat.class);
       return query.getResultList();
    }

    public List<Seat getSeatsByRoom(String room) {
        TypedQuery<Seat> query = em.createQuery(
                    "SELECT s FROM Seat s, Room r where s.name = :room and (s.roomId= c.Id)", Seat.class);

        query.setParameter("room", room);
        return query.getResultList();
    }
}


Persisting objects:

List<Room> rooms = new ArrayList<Room>();
Room roomA = new Room("roomA");
Seat a1 = new Seat("a1");
Seat a2 = new Seat("a2");

SeatService.persist(a1);
SeatService.persist(a2);

roomA.addSeat(a1);
roomA.addSeat(a2);      

RoomService.persist(roomA);
2

There are 2 best solutions below

0
On

You need to maintain both sides of bidirectional mappings. That means you also need to set the room to your seats. Add this to your code:

a1.setAssociatedRoom(roomA);
a2.setAssociatedRoom(roomA);
0
On

"setAssociatedRoom()" is called from Room class addSeat method

public void addSeat(Seat seat) {
      seat.setAssociatedRoom(this);
      seats.add(seat);
}

Is it wrong?