環境:
- 作業系統:Ubuntu 20.04 LTS
- Java:OpenJDK 17.0.3
- 春季啟動:2.6.7
- MySQL:8.0.29
當子通過父物體存盤庫持久化(保存)時,Spring Data Jpa(或一般的 Jpa)不更新子身份屬性是否正常?
考慮一下:
@Entity( name = "Company" )
@Table( name = "COMPANY" )
final public class Company
{
@Id
@GeneratedValue( strategy = GenerationType.IDENTITY )
@Column( name = "ID", updatable = false, nullable = false )
private Long id = null;
@OneToMany(
mappedBy = "company",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private Set< Phone > phoneSet = new LinkedHashSet<>();
...getters/setters...
}
@Entity( name = "Phone" )
@Table( name = "PHONE" )
final public class Phone
{
@Id
@GeneratedValue( strategy = GenerationType.IDENTITY )
@Column( name = "ID", updatable = false, nullable = false )
private Long id = null;
@ManyToOne
@JoinColumn( name = "COMPANY_ID" )
private Company company = null;
@Column( name = "number" )
String number = null;
...getters/setters...
}
private void someClassFunction()
{
.....
Phone phone = new Phone( company, "1115551234" );
company.getPhoneSet().add( phone );
this.companyRespository.save( company ); // <<<< NOTE THIS LINE
System.out.println( "phone.id: " phone.getId() );
}
當我呼叫someClassFunction()我得到:
phone.id: null
我無法立即使用分配的資料庫ID 。我確實檢查了資料庫并插入了記錄(持久/保存)并且 MySQL 確實分配了一個 ID。如果我在另一個函式中重新加載父類(公司),則重新加載子類并具有正確的 id。
但是,如果我將someClassFunction()修改為:
private void someClassFunction()
{
.....
Phone phone = new Phone( company, "1115551234" );
company.getPhoneSet().add( phone );
this.phoneRespository.save( phone ); // <<<< NOTE THIS LINE
System.out.println( "phone.id: " phone.getId() );
}
然后呼叫someClassFunction()我得到:
phone.id: 47
我可以立即使用資料庫分配的ID 。
我沒有發現任何在線檔案或教程中披露的父/子持久(即: this.companyRespository.save(company) )行為。我被引導相信從父母那里堅持應該與直接堅持孩子一樣(即:this.phoneRespository.save(phone))。
難道我做錯了什么?我的物體定義不正確嗎?
uj5u.com熱心網友回復:
是的,這是意料之中的 - 檢查您的“保存”方法的合同。它回傳一個實體,該實體可能是您傳入的實體的副本,并且您需要檢查和使用此實體 - 當 entityManager 與資料庫同步時(在事務提交時,或者如果EntityManager 已重繪 )。
IE
Phone phone = new Phone( company, "1115551234" );
company.getPhoneSet().add( phone );
phone.setCompany(company);//Don't forget to set this!
Company mergedCompanyInstance = this.companyRespository.save( company );
Phone managedPhone = mergedCompanyInstance.getPhoneSet().get(0);//assuming you have only one in the set, otherwise, check by phone number.
System.out.println( "phone.id: " phone.getId() );
System.out.println( "managedPhone.id: " managedPhone.getId() );
Spring 在 save 方法中進行了一些內部檢查,以確定它是否應該呼叫 JPA EntityManager 合并或持久化 api。如果它呼叫merge,它會從背景關系中回傳托管物體實體(可能是你給它的一個克隆),而如果它呼叫persist,它會獲取你的實體并使其成為托管實體。它是在任何 findById 和查詢方法上回傳的托管實體。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/473248.html
上一篇:帶有GROUPBY和ORDERBY的Spring本機查詢也分頁
下一篇:更新陳述句是沒有查詢?
