gpt4 book ai didi

java - 对象引用未保存的 transient 实例 : how to flush or return saved object

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:09:59 31 4
gpt4 key购买 nike

我使用 Spring 3.2.3、Hibernate 4.2.3 和 JDK 7。

我有一个简单的实体:

@Entity
public class Language {
@Id
@GeneratedValue
private long id;

@Column(nullable = false, length = 3, unique = true)
private String code;
}

我使用带有 @Transactional 注释方法的 @Service 注释类保存了该实体的实例,该方法使用 DAO 保存实体

sessionFactory.getCurrentSession().save(object);

之后,我使用saved Language 实体创建EntityX,它在ManyToOne 关系中使用它...

lang=new Language();
// ...
languageService.saveLanguage(lang);
e=new EntityX();
// ...
e.setLanguage(lang);
otherService.saveEntity(e);

EntityX 被定义为 ...

@Entity
public class EntityX {
@ManyToOne
@JoinColumn(nullable = false)
private Language language;
// ...
}

我总是得到异常

Exception in thread "main" org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: somepackage.Language

我尝试按照其他帖子中的建议,在 EntityXLanguage 的关系中使用一些级联定义,但没有效果。

如果我使用一些 HQL 查询通过其 code 找到它来重新加载已保存的 Language 实体,那么一切正常,但它远非 '不错'。

不幸的是 org.hibernate.Sessionsave(...) 方法没有返回保存的对象。

有人知道如何解决吗?

最佳答案

您是否在单个 @Transactional 方法中编写代码?
如果不是,问题可能是,在调用任何服务方法之后,事务将被提交并清除 session 。当您尝试保存实体时,在 session 中未检测到语言对象并将其作为 transient 实例进行管理并给出错误。

如果您的代码在单个事务下,您是否在保存实体以强制 Hibernate 存储 Language 到数据库并为其分配有效的 之前尝试了 flush() @Id实体?

毕竟 - 恕我直言 - 如果你依赖于实体和语言,那么最好的选择是:

@ManyToOne(cascade = CascadeType.ALL)
private Language language;

并将您的代码更改为:

e=new EntityX();
Language lang = new Language();
// ...
e.setLanguage(lang);
otherService.saveEntity(e);

并且您不需要分两步(语言+实体)持久化实体;将语言+实体作为单个项目进行管理

PS:org.hibernate.Session 的 save(...) 方法不会返回保存的对象,因为对象将保持不变(引用不会改变),只是对象属性发生了变化(例如标记为 @Id 的属性)!

编辑:
使对象持久化(我的意思是 session.save() )不会导致立即插入/更新;没有级联提示 Hibernate 外观不会检测 EntityX 和 Language 之间的依赖关系,并且在保存 EntityX 之前不会执行 Language 的 sql 插入。
languageService.save(language) 调用不执行 session.flush() 因为你在相同的 @Transactional 下并且没有 session.commit() 不执行 session.flush() 最好的选择是语言对象仍标记为 transient 。
您可以检查一下:提取服务保存代码(语言 entityX)并将所有内容放入单个 @Transactional 并检查 Hibernate 是否仍然给您错误。
我最好的选择仍然是在中间执行 flush() 或更改映射,别无他法

关于java - 对象引用未保存的 transient 实例 : how to flush or return saved object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18293169/

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