无法使用Hibernate删除具有@OneToMany关系的父JPA实体

时间:2016-01-15 23:59:37

标签: java hibernate jpa java-ee eclipselink

我在使用Hibernate删除与子实体有scipy.optimize.linprog关系的JPA实体时遇到了问题,但使用EclipseLink而不是Hibernate作为JPA提供程序时,相同的代码工作正常。父实体上的注释是@OneToMany

使用Hibernate时,它会尝试将子实体上的连接列设置为null,因为列不允许空值而失败。使用EclipseLink时,它首先删除子实体,然后删除所需行为的父实体。

我的问题是:

  1. 为什么Hibernate和EclipseLink之间的行为有所不同?我了解JPA2中的@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}, orphanRemoval=true)orphanRemoval功能应该与两个提供商的功能相同。
  2. 我的代码中是否有任何可以更改的内容,以允许EclipseLink和Hibernate在删除父实体时的功能相同,而不首先删除子实体?一个限制是代码必须与两个JPA提供程序一起使用。
  3. 我在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 = ?)

1 个答案:

答案 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
}