我在构建应用程序时遇到此错误:
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: model.Student
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:124) [hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:58) [hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:775) [hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:748) [hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:753) [hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1146) [hibernate-entitymanager-5.0.7.Final.jar:5.0.7.Final]
... 190 more
我必须补充说,当我使用merge(std)而不是persist(std)时。比我没有问题,这也很奇怪。
这是我的实体类与GeneratedValue - > GenerationType.AUTO):
@Entity
@NamedQueries({@NamedQuery(name = Student.QRY_GET_STUDENTS, query = "select s from Student s")})
public class Student {
public static final String QRY_GET_STUDENTS = "studentQuery";
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Size(min = 3, max = 70)
private String name;
@Size(min = 7, max = 7, message = "Matrikelnummer muss 7 Ziffern haben!")
private String matriculationNumber;
@DecimalMax(value = "5.0", message = "Note muss zwischen 1.0 und 5.0 sein!")
private double note;
private String lecture;
}
这就是我的持久性等级:
@Stateless
@Transactional
public class StudentPersistence {
@PersistenceContext(unitName = "UniPortalDS")
private EntityManager em;
public List<Student> getStudent() {
return (List<Student>) em.createNamedQuery("studentQuery").getResultList();
}
public List<Student> saveAllStudentsPersistence(@Nonnull Student std) {
TypedQuery<Student> q = em.createNamedQuery(std.QRY_GET_STUDENTS, Student.class);
em.persist(std);
return q.getResultList();
}
}
最后是我的服务类:
@Stateless
public class StudentService {
@EJB
private StudentPersistence studentPersistence;
public List<Student> getStudent() {
return studentPersistence.getStudent();
}
//Jetzt -->
public void saveStudentsNew(@Nonnull Student std) {
studentPersistence.saveAllStudentsPersistence(std);
}
}
答案 0 :(得分:0)
在JPA中,“非持久性”和“分离式”不是一回事:
非持久性:数据库中当前不存在这些实体。您可以使用非持久性实体,在其上调用persist()
,这应该使其持久化(即将其存储在数据库中)。
分离:这些实体确实存在于数据库中,但目前尚未被EntityManager
管理。 persist()
它们没有任何意义,因为虽然它们目前是分离的,但它们已经是持久性的,我认为这是Hibernate与您沟通的错误。但是,您可以merge()
它们,即将它们与持久性上下文同步并将它们转换为EntityManager
管理的实体,以便将更改发送到DB(1)。
(1)实际上,merge()
并未将实体从分离转换为托管;它所做的是将某个实体置于它所处的任何状态,并返回一个相应的托管实例。原始实例保持原状。