Java 如何修复 Hibernate“对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例”错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2302802/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to fix the Hibernate "object references an unsaved transient instance - save the transient instance before flushing" error
提问by Tushar Ahirrao
I receive following error when I save the object using Hibernate
使用 Hibernate 保存对象时收到以下错误
object references an unsaved transient instance - save the transient instance before flushing
采纳答案by Bozho
You should include cascade="all"
(if using xml) or cascade=CascadeType.ALL
(if using annotations) on your collection mapping.
您应该在集合映射中包含cascade="all"
(如果使用 xml)或cascade=CascadeType.ALL
(如果使用注释)。
This happens because you have a collection in your entity, and that collection has one or more items which are not present in the database. By specifying the above options you tell hibernate to save them to the database when saving their parent.
发生这种情况是因为您的实体中有一个集合,并且该集合具有一个或多个数据库中不存在的项目。通过指定上述选项,您可以告诉 hibernate 在保存它们的父项时将它们保存到数据库中。
回答by nanospeck
This isn't the only reason for the error. I encountered it just now for a typo error in my coding, which I believe, set a value of an entity which was already saved.
这不是错误的唯一原因。我刚刚在编码中遇到了拼写错误,我相信它设置了一个已经保存的实体的值。
X x2 = new X();
x.setXid(memberid); // Error happened here - x was a previous global entity I created earlier
Y.setX(x2);
I spotted the error by finding exactly which variable caused the error (in this case String xid
). I used a catch
around the whole block of code that saved the entity and printed the traces.
我通过准确找出导致错误的变量(在本例中String xid
)来发现错误。我使用了catch
整个代码块来保存实体并打印跟踪。
{
code block that performed the operation
} catch (Exception e) {
e.printStackTrace(); // put a break-point here and inspect the 'e'
return ERROR;
}
回答by McDonald Noland
I believe this might be just repeat answer, but just to clarify, I got this on a @OneToOne
mapping as well as a @OneToMany
. In both cases, it was the fact that the Child
object I was adding to the Parent
wasn't saved in the database yet. So when I added the Child
to the Parent
, then saved the Parent
, Hibernate would toss the "object references an unsaved transient instance - save the transient instance before flushing"
message when saving the Parent.
我相信这可能只是重复答案,但为了澄清起见,我在@OneToOne
映射和@OneToMany
. 在这两种情况下,事实是Child
我添加到 的对象Parent
尚未保存在数据库中。所以,当我加入Child
到了Parent
,然后将其保存的Parent
,休眠会折腾"object references an unsaved transient instance - save the transient instance before flushing"
保存父时的消息。
Adding in the cascade = {CascadeType.ALL}
on the Parent's
reference to the Child
solved the problem in both cases. This saved the Child
and the Parent
.
在这两种情况下都添加了cascade = {CascadeType.ALL}
对解决问题的Parent's
参考Child
。这保存了Child
和Parent
。
Sorry for any repeat answers, just wanted to further clarify for folks.
对不起,任何重复的答案,只是想为人们进一步澄清。
@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "performancelog_id")
public PerformanceLog getPerformanceLog() {
return performanceLog;
}
回答by Haris Osmanagi?
Or, if you want to use minimal "powers" (e.g. if you don't want a cascade delete) to achieve what you want, use
或者,如果您想使用最小的“权力”(例如,如果您不想级联删除)来实现您想要的,请使用
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
...
@Cascade({CascadeType.SAVE_UPDATE})
private Set<Child> children;
回答by Cookalino
This happens when saving an object when Hibernate thinks it needs to save an object that is associated with the one you are saving.
当 Hibernate 认为它需要保存与您正在保存的对象相关联的对象时,会在保存对象时发生这种情况。
I had this problem and did not want to save changes to the referenced object so I wanted the cascade type to be NONE.
我遇到了这个问题,不想保存对引用对象的更改,所以我希望级联类型为 NONE。
The trick is to ensure that the ID and VERSION in the referenced object is set so that Hibernate does not think that the referenced object is a new object that needs saving. This worked for me.
诀窍是确保引用对象中的 ID 和 VERSION 已设置,以便 Hibernate 不会认为引用的对象是需要保存的新对象。这对我有用。
Look through all of the relationships in the class you are saving to work out the associated objects (and the associated objects of the associated objects) and ensure that the ID and VERSION is set in all objects of the object tree.
查看您正在保存的类中的所有关系以计算出关联对象(以及关联对象的关联对象),并确保在对象树的所有对象中设置了 ID 和 VERSION。
回答by dukethrash
This occurred for me when persisting an entity in which the existing record in the database had a NULL value for the field annotated with @Version (for optimistic locking). Updating the NULL value to 0 in the database corrected this.
这发生在我持久化一个实体时,其中数据库中的现有记录对于用@Version(用于乐观锁定)注释的字段具有 NULL 值。将数据库中的 NULL 值更新为 0 更正了这一点。
回答by Joabe Lucena
If your collection is nullable just try: object.SetYouColection(null);
如果您的集合可以为空,请尝试: object.SetYouColection(null);
回答by allap
In my case it was caused by not having CascadeType
on the @ManyToOne
side of the bidirectional relationship. To be more precise, I had CascadeType.ALL
on @OneToMany
side and did not have it on @ManyToOne
. Adding CascadeType.ALL
to @ManyToOne
resolved the issue.
One-to-manyside:
在我的情况下,它是由尚未造成CascadeType
的@ManyToOne
双向关系的一面。更准确地说,我CascadeType.ALL
在@OneToMany
一边,没有在@ManyToOne
。添加CascadeType.ALL
以@ManyToOne
解决问题。
一对多侧:
@OneToMany(cascade = CascadeType.ALL, mappedBy="globalConfig", orphanRemoval = true)
private Set<GlobalConfigScope>gcScopeSet;
Many-to-one side(caused the problem)
多对一(导致问题)
@ManyToOne
@JoinColumn(name="global_config_id")
private GlobalConfig globalConfig;
Many-to-one(fixed by adding CascadeType.PERSIST
)
多对一(通过添加固定CascadeType.PERSIST
)
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name="global_config_id")
private GlobalConfig globalConfig;
回答by acpuma
i get this error when i use
我在使用时收到此错误
getSession().save(object)
but it works with no problem when I use
但是当我使用时它没有问题
getSession().saveOrUpdate(object)
回答by Jeremy Goodell
One other possible reason: in my case, I was attempting to save the child before saving the parent, on a brand new entity.
另一个可能的原因:就我而言,我试图在一个全新的实体上拯救孩子,然后再拯救父母。
The code was something like this in a User.java model:
User.java 模型中的代码是这样的:
this.lastName = lastName;
this.isAdmin = isAdmin;
this.accountStatus = "Active";
this.setNewPassword(password);
this.timeJoin = new Date();
create();
The setNewPassword() method creates a PasswordHistory record and adds it to the history collection in User. Since the create() statement hadn't been executed yet for the parent, it was trying to save to a collection of an entity that hadn't yet been created. All I had to do to fix it was to move the setNewPassword() call after the call to create().
setNewPassword() 方法创建一个 PasswordHistory 记录并将其添加到 User 中的历史记录集合中。由于尚未为父级执行 create() 语句,因此它试图保存到尚未创建的实体的集合中。我所要做的就是在调用 create() 之后移动 setNewPassword() 调用来修复它。
this.lastName = lastName;
this.isAdmin = isAdmin;
this.accountStatus = "Active";
this.timeJoin = new Date();
create();
this.setNewPassword(password);