object引用未保存的瞬态实例:如何刷新或返回保存的对象
我使用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);
之后我使用保存的 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
我尝试在EntityX
与其他post中建议的Language
关系中使用一些级联定义,但它没有任何效果。
如果我通过使用一些HQL查询通过其code
查找保存的Language
实体来重新加载,那么一切正常,但它远离“好”。
不幸的是, org.hibernate.Session
的save(...)
方法没有返回保存的对象。
有任何想法如何解决它?
你是用单个@Transactional
方法编码的吗?
如果不是问题,那么在调用service方法之后,事务将被提交并且会话被清除。 当您尝试保存实体时,在会话中未检测到语言对象并将其作为临时实例进行管理并提供错误。
如果您的代码在单个事务下,您是否在保存实体之前尝试flush()
以强制Hibernate存储Language
到数据库并为其分配有效的@Id
entifier?
毕竟 – 恕我直言 – 如果你有实体和语言的依赖,最好的选择是:
@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和语言之间的依赖关系,并且在保存EntityX之前不执行语言的sql插入。
languageService.save(language)调用不执行session.flush()因为你在同一个@Transactional
而没有session.commit()没有执行session.flush(),最好的选择是Language对象仍被标记为transient 。
您可以进行检查:提取服务保存代码(语言entityX)并将所有内容放在单个@Transactional
并检查Hibernate是否仍然给您错误。
我最好的选择仍然是在中间执行flush()或更改映射,别无他法
首先,如果code
字段是主键(或者您至少将它用作Hibernate的主要ID),请指定@Id:
@Id @GeneratedValue(generator="assigned") @Column(length = 3) private String code;
不指定ID列可能会让Hibernate有点困惑; 虽然不引用我的话。
如果save()
在此之后仍然无效,则可以使用merge()
:
Language lang = new Language("XYZ"); lang = session.merge(lange);
- 使用Oracle 10g中的Hibernate将数据保存到Clob中
- java.lang.NoClassDefFoundError:org / hibernate / cache / EntityRegion配置EHCache
- spring-hibernate花费更多时间的原因是什么?
- 使用PostgreSQL中的Schema的Hibernate和多租户数据库
- 为什么在Dao设计模式或其他设计模式中使用接口
- 如何从不同的位置加载hibernate.cfg.xml
- 如何使用Hibernate检索一组成员对象?
- @Entity实体无法解析为某个类型
- Hibernate Annotations上的Assigned Generator类