EclipseLink/JPA2 ManyToOne 双向级联持续存在问题
这类似于 如何使用 JPA/EclipseLink 级联持久化
我有像这样的实体。一种是 RoomEntity,它与 ComputerEntity 具有一对多的双向关系。例如。每个房间有 0..n 台电脑。
@Entity
public class ComputerEntity implements Serializable {
@Id
@GeneratedValue(generator="computerSeq",strategy= GenerationType.SEQUENCE)
@SequenceGenerator(name="computerSeq",sequenceName="SEQUENCECOMPUTERID",allocationSize=1)
private long computerID;
@Column(name = "COMPUTERID")
public long getComputerID() {
return computerID;
}
public void setComputerID(long computerID) {
this.computerID = computerID;
}
private RoomEntity room;
@ManyToOne()
@JoinColumn(name = "ROOMID", referencedColumnName = "ROOMID")
public RoomEntity getRoom() {
return room;
}
public void setRoom(RoomEntity room) {
this.room = room;
}
} //ComputerEntity
@Entity
public class RoomEntity {
@Id
@GeneratedValue(generator="roomSeq",strategy= GenerationType.SEQUENCE)
@SequenceGenerator(name="roomSeq",sequenceName="SEQUENCEROOMID",allocationSize=1)
private long roomID;
@OneToMany(mappedBy = "room", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private Set<ComputerEntity> computers;
@javax.persistence.Column(name = "ROOMID")
public long getRoomID() {
return roomID;
}
public void setRoomID(long roomID) {
this.roomID = roomID;
}
public Set<ComputerEntity> getComputers() {
return computers;
}
public void setComputers(Set<ComputerEntity> computers) {
for(ComputerEntity computer : computers) {
computer.setRoom(this);
}
this.computers = computers;
}
}//RoomEntity
当我尝试使用计算机持久保存一个新房间时,如下所示:
RoomEntity room = new RoomEntity();
room.setAdministrator("Fox Moulder");
room.setLocation("Area 51");
ComputerEntity computer1 = new ComputerEntity();
computer1.setDescription("Alienware area51 laptop");
Set<ComputerEntity> computers = new HashSet<ComputerEntity>();
computers.add(computer1);
room.setComputers(computers);
roomBean.createRoom(room);
roomBean 是无状态 EJB,而 roomBean.createRoom 只需调用entityManager.persist(room)。由于我在 RoomEntity 的计算机字段上有 CascadeType.PERSIST,因此创建了 ComptuerEntity。但是,如果我查看该 ComputerEntity 的 room 字段,我会发现 room 字段为空。我本以为 Eclipselink 会自动填充房间,因为我有双向关系。为了以这种方式设置房间,我必须添加
for(ComputerEntity computer : computers) {
computer.setRoom(this);
}
到 room.setComputers(...)。这是正确的方法还是有办法让 Eclipselink 自动设置它?
谢谢。 -诺亚
This is similar to How to cascade persist using JPA/EclipseLink
I have to entities like so. One is RoomEntity that has a one to many bi-directional relationship with ComputerEntity. eg. each room has 0..n computers.
@Entity
public class ComputerEntity implements Serializable {
@Id
@GeneratedValue(generator="computerSeq",strategy= GenerationType.SEQUENCE)
@SequenceGenerator(name="computerSeq",sequenceName="SEQUENCECOMPUTERID",allocationSize=1)
private long computerID;
@Column(name = "COMPUTERID")
public long getComputerID() {
return computerID;
}
public void setComputerID(long computerID) {
this.computerID = computerID;
}
private RoomEntity room;
@ManyToOne()
@JoinColumn(name = "ROOMID", referencedColumnName = "ROOMID")
public RoomEntity getRoom() {
return room;
}
public void setRoom(RoomEntity room) {
this.room = room;
}
} //ComputerEntity
@Entity
public class RoomEntity {
@Id
@GeneratedValue(generator="roomSeq",strategy= GenerationType.SEQUENCE)
@SequenceGenerator(name="roomSeq",sequenceName="SEQUENCEROOMID",allocationSize=1)
private long roomID;
@OneToMany(mappedBy = "room", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private Set<ComputerEntity> computers;
@javax.persistence.Column(name = "ROOMID")
public long getRoomID() {
return roomID;
}
public void setRoomID(long roomID) {
this.roomID = roomID;
}
public Set<ComputerEntity> getComputers() {
return computers;
}
public void setComputers(Set<ComputerEntity> computers) {
for(ComputerEntity computer : computers) {
computer.setRoom(this);
}
this.computers = computers;
}
}//RoomEntity
When I try to persist an new room with a computer like so:
RoomEntity room = new RoomEntity();
room.setAdministrator("Fox Moulder");
room.setLocation("Area 51");
ComputerEntity computer1 = new ComputerEntity();
computer1.setDescription("Alienware area51 laptop");
Set<ComputerEntity> computers = new HashSet<ComputerEntity>();
computers.add(computer1);
room.setComputers(computers);
roomBean.createRoom(room);
roomBean is a Stateless EJB and roomBean.createRoom simply calls entityManager.persist(room). Since I have a CascadeType.PERSIST on the computers field of RoomEntity the ComptuerEntity is created. However, if I look at the room field of that ComputerEntity I see that room field is null. I would have assumed that Eclipselink would have automatically filled in the room since I have a bi-directional relationship. In order to have the room set in this way I had to add
for(ComputerEntity computer : computers) {
computer.setRoom(this);
}
to room.setComputers(...). Is this the correct approach or is there a way to get Eclipselink to automatically set this?
Thanks.
-Noah
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
JPA 中没有关系维护。 EJB 2.1 已经表明,通用关系管理效率太低而且太麻烦。
我建议添加一个 addComputer() 方法,该方法将在新添加的 ComputerEntity 上设置 RoomEntity
There is no relationship maintenance in JPA. EJB 2.1 has shown that generic relationship management is for too inefficient and cumbersome.
I recommend adding an addComputer() method that would set the RoomEntity on the newly added ComputerEntity