当前位置: 首页 > 知识库问答 >
问题:

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

韩佐
2023-03-14

在使用Hibernate删除与子实体具有@OneTomany关系的JPA实体时,我遇到了一个问题,但是在使用EclipseLink而不是Hibernate作为JPA提供程序时,相同的代码可以正常工作。父实体上的批注是@OneTomany(fetch=fetchType.eager,cascade={cascadeType.all},orphanRemoval=true)

当使用Hibernate时,它尝试将子实体上的join列设置为null,但由于该列不允许null而失败。使用EclipseLink时,它首先删除子实体,然后删除父实体,这是所需的行为。

我的问题是:

  1. 为什么Hibernate和Eclipselink的行为不同?我的理解是,JPA2中的OlphanRemoveCascaseType.Remove功能应该与这两个提供程序相同。
  2. 在删除父实体时,是否可以在代码中更改任何内容,以允许EclipseLink和Hibernate运行相同的功能,而不首先删除子实体?一个限制是代码必须同时使用两个JPA提供程序。

我在SO上发现了几个类似的问题,但大多数问题要么与JPA1.0有关,使用折旧的Hibernate注释,要么建议在@OneTomany注释上设置OphanRemoval=true

@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
}
@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
}
@Stateless
public class HouseService {

    @PersistenceContext
    private EntityManager em;

    public void deleteHouse(int houseId) {
        HouseEntity houseEntity = em.find(HouseEntity.class, houseId);
        em.remove(houseEntity);
    }
}

在Hibernate中,对数据库update ROOM set HOUSE_ID=NULL执行以下SQL语句,其中HOUSE_ID=?失败,返回ORA-01407:无法更新(“test”.“ROOM”.“HOUSE_ID”)为NULL

在EclipseLink中,首先执行SQL语句DELETE FROM WHERE(HOUSE_ID=?),然后执行SQL语句DELETE FROM HOUSE WHERE(HOUSE_ID=?)

共有1个答案

孟浩然
2023-03-14

请尝试以下操作

@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
}
 类似资料:
  • 在我的Spring/MySql系统中,我有一些Jpa实体,它们通过父关系上的joinTable在OneToMany关系中连接。在这种情况下,一个帖子有很多评论。 如果我尝试删除Post实体,问题是生成的SQL试图删除仍在连接表中的注释,从而触发外键冲突。 什么是正确的方法: 删除连接表项 删除连接表左侧父关系实体 删除连接表右侧子关系实体 要记住的一些事情: 还有其他实体通过oneTo多项关系拥有

  • 我正在用Java、Spring和JPA开发一个web应用程序。我有这两个实体,它们代表一个用户及其后续通知。当一个用户跟踪另一个用户时,被跟踪的用户将收到一个follow通知。 我想删除User并删除它的所有通知,但我想保留通知的引用用户,也就是开始跟踪主用户的用户。唯一的问题是,当我尝试删除用户时,会出现以下错误: com.mysql.jdbc.exceptions.jdbc4.mysqlint

  • 我一直试图将一个实体添加到数据库中,该实体与另一个实体有OneTo许多关系,但当我插入该实体时,它说无法插入id,因为它是null。 我已经映射了这样的父子类: 子实体: 我的json长这样: 这是hibernate抛出的错误: 错误Msg=ORA-01400:无法将NULL插入(“DQISAPPS”。“目录\备注”。“目录\ ID”) 在甲骨文。jdbc。驾驶员t4cttiore11。proce

  • 我的实体更新有问题。如你所见,我有三个实体。 包含类中的列表。 包含类中的列表。 从我的SQL语句中可以看到,字段和是唯一的。我的表中只允许该组合的一行。 当我用类的新列表更新父实体()时,我希望Hibernate删除旧列表本身并创建新实体。一个一个地更新孩子是有点困难的。这就是为什么我要直接删除所有相关的孩子。 当我更新并为其提供包含具有唯一名称的和(数据库中已存在的实体)组合的列表时,我会出现

  • 我用的是SpringBoot和JPA Hibernate。 我有这些实体: 当我尝试删除父实体(Post)时,所有相关实体注释都保留在数据库中。为什么级联删除不起作用?

  • 问题内容: 我很长一段时间以来一直遇到这个问题,我已经在网上和网上搜索了SO,但尚未找到解决方案。我希望你能在这方面帮助我。 我在两个实体之间有一个父子关系,如下所示: 关键是,当我创建一个新的子代并将其分配给父代时,父代已经在缓存中时不会更新。 我尝试使用@PreUpdate在持久保留子级时将其自动添加到父级,但是如果我们在2个不同的线程中有2个实体管理器(例如在JBoss中),问题仍然存在,直