簡體   English   中英

javax.persistence.PersistenceException:org.hibernate.PersistentObjectException:error

[英]javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: error

我在JPA項目中有2個實體:

一個類別和一個問題。 所以每個類別都會有一個問題列表,每個問題都將成為一個類別的一部分(OnetoMany關系)。 我通過兩個實體中的set / add方法管理雙向關系:

題 :

    @ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "Qcategory")
private Category category;

public void setCategory(Category category) {
 this.category = category;

 if (category != null && !category.getQuestions().contains(this)) {
 category.addQuestion(this);
 }
 }

分類:

@OneToMany(cascade = { CascadeType.ALL }, mappedBy = "category")
private List<Question> questions= new ArrayList<Question>();


 public void addQuestion(Question question) {
 this.questions.add(question);

 if (question.getCategory() != this) {
 question.setCategory(this);
 }

 }

我首先創建一個類別。

Category category1 = new Category();
category1.setName = "exampleCategory";

我通過我的存儲庫將其添加到數據庫中(以類似於addOrUpdate的方式添加,如下所示)

之后我創建了一個問題

Question question1 = new Question();

我將問題的類別設置為category1

question.setCategory = category1;

在此之后,我還嘗試通過調用下面的addOrUpdate方法將問題持久化到db。 然后我收到一個錯誤:

....:javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: jpa.entities.Category

我使用的存儲庫方法如下:

@Override
public boolean addOrUpdate(Question question) {
    EntityManagerFactory emf = JPARepositoryFactory
            .getEntityManagerFactory();
    EntityManager em = emf.createEntityManager();
    EntityTransaction tx = em.getTransaction();
    tx.begin();

    Question tempQuestion = null;
    try {
        if (question.getId() != null) {
            tempQuestion = em.find(Question.class,
                    question.getId());
        }

        if (tempQuestion == null) {
            em.persist(question);
        } else {

            tempQuestion .setCategory(question.getCategory());
            ... (other setters)
            tempQuestion = em.merge(question);
        }
    } catch (Exception e) {
        ....logging...      }
    tx.commit();
    em.close();
    emf.close();
    return true;
}

任何建議都會受到歡迎。

因此,您只能在實體上調用一次persist。 該錯誤意味着您已經在傳入的Question對象上調用了persist,但是您在另一個事務中執行了此操作。 如果要將Question對象重新附加到持久性上下文,則需要調用merge或從數據庫重新加載它。

在持久化或合並之前您需要做的是在每個問題中設置類別引用。

[注意:這可能不是直接的答案,只有少數觀察]

  1. 使用每個方法調用初始化EntityManagerFactory絕對不是一個好習慣。 相反,應該在應用程序啟動期間創建一次。

  2. 您正在傳遞Category ,它是addOrUpdate的另一個持久性上下文的一部分,它不在托管狀態。

  3. 你對你的關系有什么cascade=MERGE / cascade=PERSISTcascade=ALL

  4. 也許,你可以獲取Category在當前thransaction再次ID和設置它在question堅持之前。

來自文檔:

雙向關系必須遵循這些規則。

  • 雙向關系的反面必須通過使用@OneToOne,@ OneToMany或@ManyToMany注釋的mappedBy元素來引用其擁有方。 mappedBy元素指定作為關系所有者的實體中的屬性或字段。
  • 多對一雙向關系的許多方面不能定義mappedBy元素。 許多方面始終是這種關系的擁有方。
  • 對於一對一的雙向關系,擁有方對應於包含相應外鍵的一側。
  • 對於多對多雙向關系,任何一方都可能是擁有方。

暫無
暫無

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

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