gpt4 book ai didi

java - Hibernate - 一对多关系和 orphanRemoval 级联

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:36:43 26 4
gpt4 key购买 nike

我在 Hibernate 引用书的第 21 章中有一个基本的一对多父/子关系。
级联仅从子级到父级(持久级联只是因为我不想删除子级时删除父级)。
当我将一个 child 添加到 parent 并保存 child 时,我有一个 TransientObjectException ...

@Entity
public class Parent implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@OneToMany(mappedBy = "parent", orphanRemoval = true)
private List<Child> childs;

public List<Child> getChilds() {
return childs;
}

public void setChilds(List<Child> childs) {
this.childs = childs;
}

public void addChild(Child child) {
if (childs == null) childs = new ArrayList<Child>();
if (childs.add(child)) child.setParent(this);
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}
}

@Entity
public class Child implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@ManyToOne(optional = false)
@Cascade( { PERSIST, MERGE, REFRESH, SAVE_UPDATE, REPLICATE, LOCK, DETACH })
private Parent parent;

public Parent getParent() {
return parent;
}

public void setParent(Parent parent) {
this.parent = parent;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}
}


@Test
public void test() {
Parent parent = new Parent();
Child child = new Child();
parent.addChild(child);
genericDao.saveOrUpdate(child);
}

但是在 saveOrUpdate 上,我有这个异常(exception):

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: Child
at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:244)
at org.hibernate.collection.AbstractPersistentCollection.getOrphans(AbstractPersistentCollection.java:911)
at org.hibernate.collection.PersistentBag.getOrphans(PersistentBag.java:143)
at org.hibernate.engine.CollectionEntry.getOrphans(CollectionEntry.java:373)
at org.hibernate.engine.Cascade.deleteOrphans(Cascade.java:471)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:455)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:362)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:338)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:476)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:354)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:669)
at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:252)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:451)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:669)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:665)

我真的不明白,因为拯救 child 应该通过级联拯救 parent ......有什么想法吗?

更新 1
这个问题似乎与“orphanRemoval”有关,因为如果我在父级上评论它:

@OneToMany(mappedBy = "parent" /*, orphanRemoval = true */)
private List<Child> childs;

有效!
它救了 child ,然后救了 parent 。
但是当我从其 parent 那里删除一个 child 时,我真的需要通过级联删除孤儿。

更新 2
我创建了一个 JIRA 问题:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-5364

更新 3
它似乎是固定的:-)
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2269

最佳答案

这是 Hibernate 中的一个问题,现在已修复:

http://opensource.atlassian.com/projects/hibernate/browse/HHH-2269

关于java - Hibernate - 一对多关系和 orphanRemoval 级联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3204252/

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