我使用Spring3.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;
}我使用一个@Service注释类保存了这个实体的一个实例,并使用了一个@Transactional注释方法,该方法使用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与Language的关系中使用其他帖子中的一些级联定义,但没有效果。
如果我使用一些HQL查询通过Language实体的code找到保存的code实体,那么一切都很好,但它离‘好’还差得很远。
不幸的是,save(...)方法的org.hibernate.Session没有返回保存的对象。
有谁知道怎么解决这个问题吗?
发布于 2013-08-18 16:09:07
您是在单个@Transactional方法中编码吗?
如果不是,问题可能是,在调用服务方法之后,事务将被提交并清除会话。当您试图保存实体时,不会在会话中检测到语言对象,并将其作为临时实例进行管理,并给出错误。
如果您的代码位于单个事务下,那么在保存实体之前是否尝试过一个flush(),以强制Hibernate存储Language到数据库,并为其分配一个有效的@Id实体?
毕竟- IMHO -如果您有实体和语言的依赖,最好的选择是:
@ManyToOne(cascade = CascadeType.ALL)
private Language language;并将代码更改为:
e=new EntityX();
Language lang = new Language();
// ...
e.setLanguage(lang);
otherService.saveEntity(e);并且您不需要在两个步骤(语言+实体)中持久化实体;将language+entity管理为单个项
:保存(.)org.hibernate.Session的方法不返回保存的对象,因为对象将保持不变(引用不会更改),只会更改对象属性(例如,标记此@Id的对象)!
编辑:
使对象持久(我的意思是session.save())不会导致立即插入/更新;没有级联提示,Hibernate外观不会检测到EntityX和语言之间的依赖,并且在保存EntityX之前不会执行EntityX插入。
languageService.save( Language )调用不执行session.flush(),因为您在同一个@Transactional下,没有session.commit(),没有执行session.flush(),最好的选择是语言对象仍然标记为瞬态。
您可以进行检查:提取服务、保存代码(语言为entityX),并将其全部放在单个@Transactional中,并检查Hibernate是否仍然给您带来错误。
我最好的选择仍然是在中间执行刷新()或更改映射,没有其他方法。
发布于 2013-08-17 22:25:22
首先,如果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);https://stackoverflow.com/questions/18293169
复制相似问题