Java 休眠异常:传递给持久化的分离实体
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19610608/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate Exception : detached entity passed to persist
提问by Supun Sameera
I'm trying to insert a person pojo to mysql db using Hibernate EntityManager persist method,
我正在尝试使用 Hibernate EntityManager 持久方法将一个人 pojo 插入到 mysql db,
entityManagerTransactionService.getEntityManager().persist(TemplateObject);
and getting this exception,
并得到这个例外,
javax.persistence.PersistenceException:
org.hibernate.PersistentObjectException: detached entity passed to
persist: com.esupu.base.model.pojo.common.TitleType at
org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387)....
and there is more..
还有更多..
Caused by: org.hibernate.PersistentObjectException: detached entity
passed to persist: com.esupu.base.model.pojo.common.TitleType at
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:141)
at
org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:843)
My Person.java class is,
我的 Person.java 类是,
@Entity
public class Person extends TemplateObject {
@OneToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST,CascadeType.REFRESH })
private TitleType titleType;
private String middle;
private String last;
@OneToOne(cascade = { CascadeType.ALL })
private Address address;
private Date birthdate;
private String email;
private String telephone;
private String fax;
@OneToOne(cascade = { CascadeType.ALL })
private Location location;
@OneToOne(cascade = { CascadeType.ALL })
private Country country;
and then the getter setter methods of the pojo ..
然后是 pojo 的 getter setter 方法..
the error throwing TitleType class is a "public static final" title type definition provider,
抛出 TitleType 类的错误是“public static final”标题类型定义提供程序,
@Entity
public class TitleType extends TemplateObject {
/**
*
*/
private static final long serialVersionUID = 3104954552111621034L;
private TitleType(int id, String name) {
setId(id);
setName(name);
}
public static final TitleType MR = new TitleType(1, "Mr");
public static final TitleType MISS = new TitleType(2, "Miss");
public static final TitleType MRS = new TitleType(3, "Mrs");
public static final TitleType MS = new TitleType(4, "Ms");
public static final TitleType DOCTOR = new TitleType(5, "Doctor");
public static final TitleType PROFESSOR = new TitleType(6, "Professor");
public static final TitleType SIR = new TitleType(7, "Sir");
public static final TitleType MADAM = new TitleType(8, "Madam");
}
I'm setting the title type class to the the person as,
我将标题类型类设置为该人,
person.setTitleType(TitleType.MR);
is it impossible to pass a public static final type defined class to Hibernate? or is there anything that I'm doing wrong?
是否不可能将公共静态最终类型定义的类传递给 Hibernate?还是我做错了什么?
Thanks in advance
提前致谢
采纳答案by Supun Sameera
The objects you are trying to persist include TitleType
that should not have ID
values. Otherwise Hibernate will check to see if that object is persistent or detached in the session context. If you don't want to persist some fields of your object like that you could use @Transient
annotation to exclude those fields from the fields map when persisting the entity. This is not good to hardcode IDs in the DAOs or entities because these values could be generated by some generator but if you manually updated the database with this constants you could at least define these IDs as constants in your code and load objects from session by ID before initialize the transient or persistent instance.
您尝试保留的对象包括TitleType
不应具有ID
值的对象。否则 Hibernate 将检查该对象在会话上下文中是持久的还是分离的。如果您不想像这样持久化对象的某些字段,则可以@Transient
在持久化实体时使用注释从字段映射中排除这些字段。这对 DAO 或实体中的 ID 进行硬编码并不好,因为这些值可能由某个生成器生成,但是如果您使用此常量手动更新数据库,您至少可以在代码中将这些 ID 定义为常量,并通过 ID 从会话加载对象在初始化瞬态或持久实例之前。
回答by dognose
Instead of doing this: public static final TitleType MR = new TitleType(1, "Mr");
而不是这样做: public static final TitleType MR = new TitleType(1, "Mr");
You should use the EntityManager to fetch that Object. Otherwhise Hibernate will notice, that this Object (with id 1) is already stored, but since you did not load it, the entity manager does not have it inside its own collection -> that's a detached entity.
您应该使用 EntityManager 来获取该对象。否则 Hibernate 会注意到,这个对象(id 为 1)已经存储,但是由于您没有加载它,实体管理器在它自己的集合中没有它 -> 这是一个分离的实体。
So, you should do:
所以,你应该这样做:
TitleType MR = em.find(TitleType.class, 1);
Person p = new Person(...);
p.setTitleType(MR);
em.merge(p);