我在使用Hibernate删除与子实体有scipy.optimize.linprog
关系的JPA实体时遇到了问题,但使用EclipseLink而不是Hibernate作为JPA提供程序时,相同的代码工作正常。父实体上的注释是@OneToMany
使用Hibernate时,它会尝试将子实体上的连接列设置为null,因为列不允许空值而失败。使用EclipseLink时,它首先删除子实体,然后删除所需行为的父实体。
我的问题是:
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}, orphanRemoval=true)
和orphanRemoval
功能应该与两个提供商的功能相同。我在SO上发现了几个类似的问题,但是大多数都与JPA 1.0有关,使用折旧的Hibernate注释或建议在CascaseType.REMOVE
注释上设置orphanRemoval=true
。
我使用的Hibernate版本是4.3.10.Final,EclipseLink的版本是2.5.2。
为了证明这个问题,我创建了以下相对简单的例子。
父实体的代码如下:
@OneToMany
子实体的代码如下:
@Entity
@Table(name="HOUSE")
public class HouseEntity {
@Id
@Column(name="HOUSE_ID")
private int houseId;
@Column(name="HOUSE_NAME")
private String houseName;
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}, orphanRemoval=true)
@JoinColumn(name = "HOUSE_ID", referencedColumnName = "HOUSE_ID")
private List<RoomEntity> rooms;
//Getters, setters, equals, and hashCode omitted
}
用于删除父实体的EJB代码如下:
@Entity
@Table(name="ROOM")
public class RoomEntity {
@Id
@Column(name="ROOM_ID")
private int roomId;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "HOUSE_ID", referencedColumnName = "HOUSE_ID")
private HouseEntity house;
@Column(name="ROOM_NAME")
private String roomName;
//Getters, setters, equals, and hashCode omitted
}
在Hibernate中,对数据库执行以下SQL语句
@Stateless
public class HouseService {
@PersistenceContext
private EntityManager em;
public void deleteHouse(int houseId) {
HouseEntity houseEntity = em.find(HouseEntity.class, houseId);
em.remove(houseEntity);
}
}
以update ROOM set HOUSE_ID=null where HOUSE_ID=?
ORA-01407: cannot update ("TEST"."ROOM"."HOUSE_ID") to NULL
在EclipseLink中,首先执行SQL语句DELETE FROM ROOM WHERE (HOUSE_ID = ?)
,然后执行SQL语句DELETE FROM HOUSE WHERE (HOUSE_ID = ?)
。
答案 0 :(得分:1)
尝试以下
@Entity
@Table(name="HOUSE")
public class HouseEntity {
@Id
@Column(name="HOUSE_ID")
private int houseId;
@Column(name="HOUSE_NAME")
private String houseName;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "house", cascade = CascadeType.ALL)
private List<RoomEntity> rooms;
//Getters, setters, equals, and hashCode omitted
}
@Entity
@Table(name="ROOM")
public class RoomEntity {
@Id
@Column(name="ROOM_ID")
private int roomId;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "HOUSE_ID", referencedColumnName = "HOUSE_ID", nullable = false)
private HouseEntity house;
@Column(name="ROOM_NAME")
private String roomName;
//Getters, setters, equals, and hashCode omitted
}