对象引用未保存的瞬态实例:在刷新之前保存瞬态实例[重复]
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:对象引用了未保存的瞬态实例 - 在刷新之前保存瞬态实例