簡體   English   中英

調用 EntityManager.merge() 時未設置 ID

[英]Id not being set when calling EntityManager.merge()

我在 2 object Parent & Child 之間有一個簡單的 OneToMany 關聯,如下所示。

父實體

    @Entity
    public class Parent {
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     private Long id;
     private String name;
     @Version
     private Long version;

      @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
      List<Child> children = new ArrayList<Child>();

      ....
    }

子實體

    @Entity
    public class Child {
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private Long id;
      private String name;
      @Version
      private Long version;
        ...
    }

以下是我的測試,它加載現有父級添加一個子級並在父級上調用 EntityManager.merge()。

    @Test
public void testParent(){
    Parent parent = (Parent) dao.loadParent(Parent.class, parentId);

    Child c = new Child();
    c.setName("c");

    parent.getChildren().add(c);

    dao.mergeEntity(parent);

    Assert.assertNotNull(c.getId());
}

測試 id 的主鍵的斷言失敗。 我看到記錄與自動分配的主鍵一起正確插入到數據庫中。

我所有的 DAO 調用都圍繞事務進行,並按要求進行傳播。

EntityManager.merge(..)獲取一個實例並返回一個托管實例。 如果是瞬態實例,它會返回一個新實例(不修改原始實例)

所以你的mergeEntity(..)方法應該return em.merge(entity)

由於您的 id 是由數據庫設置的,因此 JPA/Hibernate 只能在 SQL 語句發送到數據庫之后才能設置它。 如果您將 Hibernate 配置為顯示 sql 語句或將日志更改為 DEBUG 您可能會看到在調用mergeEntity時沒有發出 SQL 語句。

使您的測試工作的一種方法應該是在對子 ID 進行斷言之前添加 em.flush()。

您管理事務的方式可能存在問題,但需要查看 DAO 的代碼以及您在單元測試中獲取對 DAO 的引用的方式。

暫無
暫無

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

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