axc*_*dnt 194 java hibernate hibernate-mapping
我在尝试更新我的实体时遇到以下问题:
"A collection with cascade=”all-delete-orphan” was no longer referenced by the owning entity instance".
Run Code Online (Sandbox Code Playgroud)
我有一个父实体,它有Set<...>一些子实体.当我尝试更新它时,我将所有引用设置为此集合并进行设置.
以下代码表示我的映射:
@OneToMany(mappedBy = "parentEntity", fetch = FetchType.EAGER)
@Cascade({ CascadeType.ALL, CascadeType.DELETE_ORPHAN })
public Set<ChildEntity> getChildren() {
return this.children;
}
Run Code Online (Sandbox Code Playgroud)
我试图只清理Set <..>,根据这个:如何"可能"解决问题,但它不起作用.
如果您有任何想法,请告诉我.
谢谢!
bra*_*mus 194
检查您为sonEntities分配内容的所有地方.您引用的链接明确指出创建一个新的HashSet,但您可以在重新分配该集时随时出现此错误.例如:
public void setChildren(Set<SonEntity> aSet)
{
this.sonEntities = aSet; //This will override the set that Hibernate is tracking.
}
Run Code Online (Sandbox Code Playgroud)
通常,您只想在构造函数中"设置"一次"新".每当您想要添加或删除列表中的内容时,您必须修改列表的内容而不是分配新列表.
要添加孩子:
public void addChild(SonEntity aSon)
{
this.sonEntities.add(aSon);
}
Run Code Online (Sandbox Code Playgroud)
要删除孩子:
public void removeChild(SonEntity aSon)
{
this.sonEntities.remove(aSon);
}
Run Code Online (Sandbox Code Playgroud)
Man*_*anu 96
方法:
public void setChildren(Set<SonEntity> aSet) {
this.sonEntities = aSet;
}
Run Code Online (Sandbox Code Playgroud)
如果parentEntity已分离则可以工作,如果我们更新则会再次工作.
但是如果实体没有从每个上下文中分离出来(即查找和更新操作在同一个事务中),则以下方法有效.
public void setChildren(Set<SonEntity> aSet) {
//this.sonEntities = aSet; //This will override the set that Hibernate is tracking.
this.sonEntities.clear();
if (aSet != null) {
this.sonEntities.addAll(aSet);
}
}
Run Code Online (Sandbox Code Playgroud)
xpu*_*mos 26
当我在各种地方读到hibernate不喜欢你分配给一个集合时,我认为最安全的事情显然是让它最终像这样:
class User {
private final Set<Role> roles = new HashSet<>();
public void setRoles(Set<Role> roles) {
this.roles.retainAll(roles);
this.roles.addAll(roles);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这不起作用,并且你得到了可怕的"不再引用"错误,这在这种情况下实际上是非常误导的.
事实证明,hibernate调用你的setRoles方法并且它希望在这里安装它的特殊集合类,并且不接受你的集合类.尽管阅读了有关未按照set方法分配到集合的所有警告,但这让我难以忍受了很长时间.
所以我改为:
public class User {
private Set<Role> roles = null;
public void setRoles(Set<Role> roles) {
if (this.roles == null) {
this.roles = roles;
} else {
this.roles.retainAll(roles);
this.roles.addAll(roles);
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,在第一次调用时,hibernate将安装其特殊类,并且在后续调用中,您可以自己使用该方法而不会破坏所有内容.如果你想把你的类用作bean,你可能需要一个工作的setter,这至少似乎有效.
axc*_*dnt 16
实际上,我的问题是关于我的实体的equals和hashcode.遗留代码可能带来很多问题,永远不要忘记检查它.我所做的只是保持delete-orphan策略并纠正equals和hashcode.
我有同样的错误.对我来说问题是,在保存实体之后,映射的集合仍然为null,并且在尝试更新实体时抛出了异常.什么对我有帮助:保存实体,然后进行刷新(集合不再为空),然后执行更新.也许使用新的ArrayList()或其他东西初始化集合也可能有所帮助.
我通过这样做修复了:
1. clear existing children list so that they are removed from database
parent.getChildren().clear();
Run Code Online (Sandbox Code Playgroud)
2. add the new children list created above to the existing list
parent.getChildren().addAll(children);
Run Code Online (Sandbox Code Playgroud)
Hope this post will help you to resolve the error
可能是由 引起的hibernate-enhance-maven-plugin。当我启用enableLazyInitialization属性时,这个异常开始在我的惰性集合上发生。我正在使用休眠5.2.17.Final。
请注意这两个休眠问题:
小智 6
我在使用 JSON 发布请求更新实体时遇到了这个问题。当我在没有关于孩子的数据的情况下更新实体时发生了错误,即使没有。添加
"children": [],
Run Code Online (Sandbox Code Playgroud)
到请求正文解决了问题。
所有这些答案都没有帮助我,但我找到了另一个解决方案。
我有一个实体 A,其中包含实体 B 的列表。实体 B 包含实体 C 的列表。
我试图更新实体 A 和 B。它成功了。但是当更新实体C时,我得到了提到的错误。在实体BI中有这样的注释:
@OneToMany(mappedBy = "entity_b", cascade = [CascadeType.ALL] , orphanRemoval = true)
var c: List<EntityC>?,
Run Code Online (Sandbox Code Playgroud)
我只是删除了orphanRemoval,更新就成功了。
我使用@user2709454 方法进行了小幅改进。
public class User {
private Set<Role> roles;
public void setRoles(Set<Role> roles) {
if (this.roles == null) {
this.roles = roles;
} else if(this.roles != roles) { // not the same instance, in other case we can get ConcurrentModificationException from hibernate AbstractPersistentCollection
this.roles.clear();
if(roles != null){
this.roles.addAll(roles);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
我有同样的问题,但那是当集合为空时。仅在 Set 集合中,在 List 中工作正常。您可以尝试使用hibernate注释@LazyCollection(LazyCollectionOption.FALSE)而不是JPA注释fetch = FetchType.EAGER.
我的解决方案:这是我的配置并且工作正常
@OneToMany(mappedBy = "format", cascade = CascadeType.ALL, orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
private Set<Barcode> barcodes;
@OneToMany(mappedBy = "format", cascade = CascadeType.ALL, orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
private List<FormatAdditional> additionals;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
179062 次 |
| 最近记录: |