对象引用未保存的瞬态实例:在刷新之前保存瞬态实例[重复]

Posted

技术标签:

【中文标题】对象引用未保存的瞬态实例:在刷新之前保存瞬态实例[重复]【英文标题】:object references an unsaved transient instance : save the transient instance before flushing [duplicate] 【发布时间】:2012-05-03 22:04:57 【问题描述】:

我有两个实体:PlayerProfileEntity 和 UserInfoEntity 我加入了 userInfoEntity 和 PlaterProfileEntity 并将我的记录保存在数据库中,如下所示:

Session session = sessionFactory.openSession();
Transaction tr = session.beginTransaction();
Criteria crit = session.createCriteria(PlayerProfileEntity.class);
player.setUserId(new UserInfoEntity());
player.getUserId().setAddress(user.getUserId().getAddress());
session.save(player);
tr.commit();

我在我的 PlayerProfileEntity 类中使​​用了这个关联

@ManyToOne (fetch = FetchType.LAZY)
@Cascade(CascadeType.REFRESH)
@JoinColumn(name="userid")

我收到此错误:

org.hibernate.TransientObjectException: object references an unsaved transient instance - save     the transient instance before flushing: com.shared.entity.UserInfoEntity

注意:如果我使用 CascadeType.All,我会收到此错误:

Cannot add or update a child row: a foreign key constraint fails

知道怎么解决这个问题

谢谢

【问题讨论】:

【参考方案1】:

TransientObjectException 会在您尝试保存对象而不保存适当的联接时出现。您必须先保存 UserInfoEntity,然后才能保存您的 PlayerInfoEntity 类。

player.setUserId(new UserInfoEntity());

通过使用它,您将特定的UserInfoEntity 分配给PlayerInfoEntity。但是UserInfoEntity 没有任何ID。两者将如何映射?这就是异常到来的原因。

希望对你有帮助。

【讨论】:

【参考方案2】:

您应该使用 CascadeType.PERSIST 或 CascadeType.ALL

【讨论】:

谢谢,但我已经在使用 CascadeType.ALL,正如我的问题中提到的并得到错误:无法添加或更新子行:外键约束失败,对此有任何想法 对不起,最后没看到注释。不过,我认为,我们应该专注于您在使用 CascadeType.ALL 时遇到的错误。 您显示了涉及Criteria 的行,但这与您的代码无关。另一方面,它缺少组装您要保存的Player 的重要代码。另外,这条线让我很困惑:player.getUserId().setAddress(user.getUserId().getAddress()) 这有什么意义?而 UserId 怎么会是一个复合对象呢? 如果user是持久化对象,那么他的address也是持久化的。您将该地址设置为非持久对象player。这可能是您的问题的原因。 它与 Hibernate 感知的对象的当前状态有关。当您说session.save(o) 时,它在保存之前隐式执行session.persist(o)。你也可以自己调用。届时,Hibernate 将“注意到”您的对象并将其注册到会话中。【参考方案3】:
public void savePlayerMethod(PlayerInfoEntity player)

if(player == null)
   player = new PlayerInfoEntity();

player.setUserId(getSavedUserInfo());
Session session = SessionFactory.openSession();
Transaction transaction = session.beginTransaction();
session.save(userInfo);
transaction.committ();


public UserInfoEntity getSavedUserInfo()
UserInfoEntity userInfo = new UserInfoEntity();
Session session = SessionFactory.openSession();
Transaction transaction = session.beginTransaction();
session.save(userInfo);
transaction.committ();

【讨论】:

【参考方案4】:

我刚才在尝试通过 Session#save() 方法存储具有分配 ID 的未保存对象时遇到了同样的错误。我认为问题可能是您未保存的对象图已经被赋予了一个 id(这是保存方法试图做的事情),这以某种方式弄乱了保存方法的级联。尝试使用 Session#persist() 代替,级联应该可以使用它,即使对象已经被分配了一个 id。

【讨论】:

【参考方案5】:

我遇到了同样的问题,经过大量调试后,我发现从实体中删除 @AllArgsConstructor 并添加

@Tolerate
public <ClassName>() 

为我工作。

【讨论】:

【参考方案6】:

嗯,

我有类似的问题,我所做的是

Object tmp = session.get(Object.class,ob.getId())
if(tmp!=null)
    session.evit(tmp); // or merge

session.saveOrUpdate(ob);

这对我有用。

它获取瞬态对象并将其驱逐或合并。

现在使用 save 或 update 方法来保存你的新对象。

【讨论】:

您需要详细说明此解决方案。驱逐然后保存如何解决这个问题。通常,此问题是由没有保存附加到当前正在保存的实体的实体引起的。

以上是关于对象引用未保存的瞬态实例:在刷新之前保存瞬态实例[重复]的主要内容,如果未能解决你的问题,请参考以下文章

对象引用未保存的瞬态实例:在刷新之前保存瞬态实例[重复]

TransientObjectException - 对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例

TransientPropertyValueException:对象引用了未保存的瞬态实例 - 在刷新之前保存瞬态实例

数据未保存:对象引用了未保存的瞬态实例 - 在刷新之前保存瞬态实例 [重复]

对象引用未保存的瞬态实例 - 在刷新休眠 JPA 之前保存瞬态实例 [重复]

org.hibernate.TransientObjectException:对象引用了未保存的瞬态实例 - 在刷新之前保存瞬态实例