簡體   English   中英

Sprint Data JPA - 使用共享主鍵保存父實體的子實體

[英]Sprint Data JPA - save child entity with parent with shared primary key

我有兩個表'STUDENT'(pk - student_id autogenerated) 和'Address'。 address_id 是 Address 表的 pk,它必須與 student_id 的值相同。

實體:

@Entity
@Table(name = "student")
Public class Student{

    @Id
    @GeneratedValue
    @Column(name = "STUDENT_ID",updatable = false,insertable = false)
    private long Id;


    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="STUDENT_ID")
    private Address address;

.....
//getters setters
}


@Entity
@Table(name = "address")
Public class Address{

    @Id
    @Column(name = "ADDRSS_ID",updatable = false,insertable = false)
    private long Id;


    @OneToOne
    private Student student;

.....
//getters setters
}



service 

public class Service {

 @Autowired StudentRepository repo;

 public void saveStudent(Student s){

 repo.save(s)
}

}

我面臨的問題是因為 cascade.ALL JPA 試圖在父實體 Student 之前保存子實體,即 Address,但是 ADDRESS_ID 沒有 NULL 約束,我收到約束違規異常。 如何同時保存兩者。 請幫忙。 提前致謝

您詢問

如何同時保存(實體和關聯實體)。

讓我們將“一次性”翻譯為一次事務,實現它的方法有很多種,所有這些都在於這樣一個事實,即在提交整個事務之前在適當的時間點完成持久化實體刷新。

解決方案

一種做法是采用基於 JPA 規范並具有可延遲約束的后台緩存機制。 首先持久化StudentAddress實體,以通過刷新從數據庫中的生成器獲取 id,然后在它們之間創建適當的綁定和關聯,最后提交事務。

為了演示它,從會話抽象開始,即作為一級緩存的EntityManager ,您可以通過EntityManagerFactory實例化它,它確實代表二級緩存。

EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
entityManager.persist(Not_associated_entities);
...
flush();
...
entityManager.merge(associated_entities);
...
entityManager.getTransaction().commit();
entityManager.close();

另外專門針對PK和FK列最常被索引,所以共享PK可以減少一半的索引占用空間,這是可取的,因為你想把你所有的索引都存儲到內存中以加快索引掃描,你可以在OneToOne關聯優化中這篇文章

警告

始終關閉entityManager 的所有手動實例化。

暫無
暫無

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

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