簡體   English   中英

如何避免將分離的實體傳遞給JPA來持久化?

[英]How to avoid detached entity passed to persist in JPA?

構建應用程序時出現此錯誤:

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)時,我必須添加一點。 比我沒有問題,這也很奇怪。

那就是我的Entity類,帶有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);
    }
}

在JPA中,“非持久”和“分離”是不同的:

  • 非持久性:這些實體當前在數據庫中不存在。 您可以采用一個非持久性實體,在其上調用persist() ,這將使它持久化(即,將其存儲在數據庫中)。

  • 分離的:這些實體確實存在於數據庫中,但當前不通過EntityManager進行管理。 這是沒有意義的persist()他們,因為盡管他們目前正在脫離他們已經是持久的, 而我認為這是錯誤的Hibernate被傳達給你 但是,您可以merge()它們merge() ,即,將它們與持久性上下文同步,並將它們轉換為由EntityManager管理的實體,以便將更改發送到DB(1)。

(1)實際上, merge()不會將實體從分離狀態轉換為托管狀態; 它要做的是將某個實體處於任何狀態,然后返回相應的托管實例。 原始實例保持原樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM