对象引用未保存的瞬态实例:如何刷新或返回保存的对象 [英] object references an unsaved transient instance: how to flush or return saved object
问题描述
我有一个简单的实体:
@Entity
public class Language {
@Id
@GeneratedValue
private long id;
@Column(nullable = false,length = 3,unique = true)
私有字符串代码;
}
我使用 @保存了该实体的一个实例使用
注释类,该方法使用DAO来保存实体 @Transactional
注释方法的服务
sessionFactory.getCurrentSession()保存(对象);
之后,我使用保存 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 )
私人语言语言;
// ...
}
我总是得到异常 p>
线程main中的异常org.hibernate.TransientObjectException:对象引用一个未保存的瞬态实例 - 在flush之前保存瞬态实例:somepackage。语言
我尝试在 EntityX $ c中使用一些级联定义$ c>与
语言
的关系,正如其他帖子中所建议的那样,但它不起作用。
如果我使用一些HQL查询重新加载已保存的 Language
实体,方法是使用一些HQL查询找到它,然后一切正常,但是它很远离'好'。
不幸的是, save(...)
方法(s) org.hibernate.Session
不会返回保存的对象。
有没有人有任何想法如何解决它?
/>如果不是这个问题,那么在任何调用服务方法之后,事务将被提交并且会话被清除。当您尝试保存实体时,在会话中未检测到语言对象,并将其作为临时实例进行管理并给出错误。
如果您的代码处于单个事务中,您尝试了保存实体以强制Hibernate存储 Language
到数据库并为其分配一个有效的之前保存
entifier? flush()
> @Id
毕竟 - 恕我直言 - 如果您有来自实体和语言的依赖关系,最好的选择是:
@ManyToOne(cascade = CascadeType.ALL)
private语言语言;
并将您的代码更改为:
e = new EntityX();
语言lang = new Language();
// ...
e.setLanguage(lang);
otherService.saveEntity(e);
并且您不需要在两个步骤(语言+实体)中坚持实体;管理语言+实体作为单个项目
PS :org.hibernate.Session的save(...)方法不返回保存的对象,因为对象保持不变(引用不变),只是对象属性发生变化(例如标记为 @Id
的那个) / p>
编辑:
使对象持久化(session.save(),我的意思是)不会立即插入/更新;没有级联提示Hibernate的外观没有检测到EntityX和Language之间的依赖关系,并且在保存EntityX之前没有执行一个语言的sql插入。
languageService.save(语言)调用不执行session.flush (),因为你处于相同的 @Transactional
并且没有session.commit()。没有执行session.flush(),最好的选择是Language对象仍然被标记为transient。
你可以做一个检查:提取服务保存代码(language entityX),并把所有内容放在单独的 @Transactional
中,并检查Hibernate是否仍然给你错误
我最好的选择是在中间执行一个flush()或者改变你的映射,没有其他办法。
I use Spring 3.2.3 and Hibernate 4.2.3 and JDK 7.
I have a simple entity:
@Entity
public class Language {
@Id
@GeneratedValue
private long id;
@Column(nullable = false, length = 3, unique = true)
private String code;
}
I saved an instance of this entity using a @Service
annotated class with a @Transactional
annotated method which uses a DAO which saves the entity with
sessionFactory.getCurrentSession().save(object);
After that I used the saved Language
entity for creating EntityX
, which used it in an ManyToOne
relation ...
lang=new Language();
// ...
languageService.saveLanguage(lang);
e=new EntityX();
// ...
e.setLanguage(lang);
otherService.saveEntity(e);
and EntityX
is defined as ...
@Entity
public class EntityX {
@ManyToOne
@JoinColumn(nullable = false)
private Language language;
// ...
}
I always get the exception
Exception in thread "main" org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: somepackage.Language
I try to use some cascade-definitions in EntityX
's relation to Language
as suggested in other posts, but it has no effect.
If I reload the saved Language
entity by finding it by its code
using some HQL-query, then everything works fine, but that it is far away from being 'nice'.
Unfortunately the save(...)
method(s) of org.hibernate.Session
does not return the saved object.
Has anybody any ideas how to solve it?
Is you code in a single @Transactional
method?
If not the problem can be that, after any call to service method, transaction will be commit and session cleared. When you try to save entity, language object is not detected in session and managed as transient instance and give the error.
In case your code is under single transaction did you try a flush()
before saving entity to force Hibernate store Language
to database and assign it a valid @Id
entifier?
After all - IMHO - if you have a dependency from Entity and Language the best choice is:
@ManyToOne(cascade = CascadeType.ALL)
private Language language;
and change your code as:
e=new EntityX();
Language lang = new Language();
// ...
e.setLanguage(lang);
otherService.saveEntity(e);
and you don't need to persist entity in two steps (language + entity); manage language+entity as single item
PS: The save(...) method(s) of org.hibernate.Session does not return the saved object because the object will remain the same (reference doesn't change), just object properties changes (like the one marked this @Id
, for example)!
EDIT:
Make an object persistent (session.save() it I mean) don't result in a immediate insert/update; without cascade hint Hibernate look doesn't detect dependency between EntityX and Language and doesn't perform a sql insert of Language before saving EntityX.
languageService.save(language) call doesn't perform session.flush() because you are under same @Transactional
and without session.commit() no session.flush() is performed and best option is that Language object is still marked as transient.
You can do a check: extract services save code (language entityX) and put all in single @Transactional
and check if Hibernate still give you error.
My best option is still perform a flush() in the middle or change your mapping, no other way
这篇关于对象引用未保存的瞬态实例:如何刷新或返回保存的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!