gpt4 book ai didi

java - 如果还有其他 child ,则 Hibernate 删除 child 不起作用

转载 作者:行者123 更新时间:2023-12-02 11:12:41 24 4
gpt4 key购买 nike

有一个实体“地址”和另一个实体“建筑物”。一个地址可以有多个建筑物。

在building.java上,我确实定义了地址:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ADDRESS_ID_REF")
public Address getAddress() {
return this.address;
}

地址构建定义为:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "address")
public Set<Building> getBuildings() {
return this.buildings;
}

当尝试做的时候 em.remove(building)它确实有效

  • 当只有一个地址有建筑物时没问题
  • 当同一地址有两栋建筑物时情况会很糟糕

坏案例的构造与好案例完全相同,只是引用相同的地址将第二座建筑物插入数据库。

  • 插入地址值 ('address123', [...]);
  • 插入建筑物值 ('building234', 'address123', [...]);
  • 插入建筑物值 ('building235', 'address123', [...]);

在糟糕的情况下(hibernate 不执行任何删除),我仍然能够删除数据库中的行 ( delete from building where building_id = '123' )。没有关于引用的 SQL 错误。

在类似的线程中,我读到在这种情况下通常存在剩余引用,因此 hibernate 无法正确删除该实体。

不幸的是,我也没有得到 hibernate 的任何 log4j 输出,也没有发生异常。所以不知道hibernate的问题出在这个地方。

我的 log4j.properties 对于我的记录器来说工作得很好。输出按预期写入控制台。但我没有得到任何 Hibernate 日志记录。我在另一个线程中读到该记录器应该给我一些提示:org.hibernate.event.internal.DefaultPersistEventListener

log4j.rootLogger=TRACE, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

log4j.category.com.myproject.mypackage=INFO
log4j.category.com.myproject.mypackage.myclass=DEBUG

log4j.category.org.hibernate.event.internal.DefaultPersistEventListener=TRACE
log4j.category.org.hibernate=TRACE
log4j.category.org.springframework=TRACE

当 persistence.xml show_sql 设置为 true 时,我会将 SQL 写入控制台。在那里我可以看到没有执行删除sql。但我没有看到任何错误。

<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />

正如在其他线程中大多数情况下所写的那样,似乎还剩下一些必须首先删除的引用。但就我而言,我的实体是子对象,这意味着我不认为建筑指导中的外国问题会成为问题。此外,我可以通过 SqlDeveloper 直接删除建筑行。当更改我的代码时

em.remove(building)

em.remove(address)

由于级联,所有三个实体都被删除。但这不是我想要的,我只想删除单个建筑物。我认为要得到它,我需要查看丢失的 hibernate 日志记录(希望有一些)。

如果您需要更多信息,请询问他们。提前致谢。

最佳答案

(这将是一条评论,但我没有足够的声誉)您想要实现什么目标或改善不起作用的目标?删除建筑物不应删除地址,因为 @ManyToOne 注释中没有级联选项。如果您尝试从建筑物集中删除建筑物,则需要在 @OneToMany 注释中使用 orphanRemoval = true

编辑(阅读评论后)

最简单的方法如下:将 orphanRemoval=true 添加到 @OneToMany 地址映射。比

Building b .... // current Object to be deleted
b.getAddress().getBuildings().remove(b);
b.setAddress(null);
em.merge(a);

对于这段代码

b.getAddress().getBuildings().remove(b);
b.setAddress(null);

您可以在地址实体中创建单独的方法,例如

public void removeBuilding(Building b){
buildings.remove(b);
b.setAddress(null);
}

关于java - 如果还有其他 child ,则 Hibernate 删除 child 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50508641/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com