使用Hibernate保存对象时收到以下错误

object references an unsaved transient instance - save the transient instance before flushing

当前回答

这不是错误的唯一原因。我刚才遇到了它,因为我的代码中有一个错别字,我相信它设置了一个已经保存的实体的值。

X x2 = new X();
x.setXid(memberid); // Error happened here - x was a previous global entity I created earlier
Y.setX(x2);

我通过准确查找导致错误的变量(在本例中为Stringxid)发现了错误。我在保存实体并打印痕迹的整个代码块周围使用了捕获。

{
   code block that performed the operation
} catch (Exception e) {
   e.printStackTrace(); // put a break-point here and inspect the 'e'
   return ERROR;
}

其他回答

我相信这可能只是重复答案,但为了澄清,我在@OneToOne映射和@OneToMany上得到了这个答案。在这两种情况下,我添加到Parent的Child对象尚未保存在数据库中。因此,当我将Child添加到Parent,然后保存Parent时,Hibernate会在保存Parent之前抛出“对象引用未保存的瞬态实例-在刷新之前保存瞬态实例”消息。

在父级对子级的引用上添加cascade={CascadeType.ALL}解决了这两种情况下的问题。这保存了子对象和父对象。

很抱歉有重复的回答,只是想进一步澄清一下。

@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "performancelog_id")
public PerformanceLog getPerformanceLog() {
    return performanceLog;
}

当Hibernate认为需要保存与正在保存的对象关联的对象时,在保存对象时会发生这种情况。

我遇到了这个问题,不想保存对引用对象的更改,所以我希望级联类型为NONE。

诀窍是确保设置了被引用对象中的ID和VERSION,这样Hibernate就不会认为被引用对象是需要保存的新对象。这对我有用。

查看要保存的类中的所有关系,以计算关联对象(以及关联对象的关联对象),并确保在对象树的所有对象中设置了ID和VERSION。

或者,如果你想使用最小的“权力”(例如,如果你不想级联删除)来实现你想要的,使用

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

...

@Cascade({CascadeType.SAVE_UPDATE})
private Set<Child> children;

为完整起见:A

org.hibernate.TransientPropertyValueException 

带有消息

object references an unsaved transient instance - save the transient instance before flushing

当您试图持久化/合并一个实体并引用另一个恰好分离的实体时,也会发生这种情况。

在引入乐观锁定(@Version)之后,我对所有PUT HTTP事务都面临同样的错误

在更新实体时,必须发送该实体的id和版本。如果任何实体字段与其他实体相关,那么对于该字段,我们也应该提供id和版本值,而不是JPA首先将相关实体作为新实体持久化

示例:我们有两个实体-->Vehicle(id、Car、version);汽车(id、版本、品牌);要更新/保存车辆实体,请确保车辆实体中的“车辆”字段已提供id和版本字段