[英]Why hibernate is not deleting rows?
我正在使用JPA注釋進行冬眠的基礎知識,我有一個問題。 我創建了一個虛擬項目,其結構如下:
一名實體班級人士
@Id
@GeneratedValue(strategy=GenerationType.TABLE, generator="personIdGenerator")
private int personIdentifier;
private String firstName;
private String lastName;
private String title;
private String sex;
@ElementCollection(fetch=FetchType.LAZY)
@MapKeyEnumerated(EnumType.STRING)
@javax.persistence.MapKeyColumn(name="ADDRESS_TYPE")
private Map<AddressType,Address> address = new HashMap<AddressType, Address>();
一個可嵌入的類地址-
private String streetAddressLane1;
private String streetAddressLane2;
private String streetAddressLane3;
@ManyToOne(cascade={CascadeType.ALL},fetch=FetchType.LAZY)
private City city;
最后是一個實體類的城市-
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int cityId;
private String city;
private String state;
private String country;
private String zipCode;
現在我有一個主要的方法,代碼如下:
SessionFactory sesFac = new Configuration().configure().buildSessionFactory();
Session session = sesFac.openSession();
Transaction tx = session.beginTransaction();
// session.save(city);
//session.save(adr);
Person person = (Person) session.get(Person.class, 101);
//Employee empNew = (Employee)session.merge(emp);
//empNew.setEmpId(2);
// System.out.println(person.getAddress().get(AddressType.HOME_ADDRESS).getCity().getZipCode());
//Employee empOld= (Employee) session.get(Employee.class, empNew.getEmpId());
session.getTransaction().commit();
session.flush();
session.close();
session = sesFac.openSession();
tx = session.beginTransaction();
// session.save(city);
//session.save(adr);
person.setLastName("gggggg");
session.saveOrUpdate(person);
//Employee empNew = (Employee)session.merge(emp);
//empNew.setEmpId(2);
//Employee empOld= (Employee) session.get(Employee.class, empNew.getEmpId());
session.getTransaction().commit();
session.close();
在主要方法中,我得到了兩個不同的會話和兩個不同的事務。 在第一個記錄中,我獲取了個人ID 101的記錄,該記錄已存在於數據庫中,在第二個事務中,我將姓氏設置為gggggg。
現在,由於我使用的是惰性初始化,因此當我嘗試更改名稱並將其傳遞給saveOrUpdate方法時,不應有任何地址和城市。 因此,這應該刪除分配給個人ID 101的現有地址,但事實並非如此。 地址仍然存在,姓氏已更改為ggggg。 我不明白這可能是什么原因。 休眠創建的代理是否可以處理此類更新?
“未加載”與“已刪除”不同,並且Hibernate會跟蹤加載的所有內容之間的差異。
在這種特定情況下,當Hibernate加載Person
實體時,它將address
字段包裝在PersistentMap
,該字段最初被標記為尚未加載。 如果要訪問address
字段並讀取或更改其中的任何內容,則PersistentMap
會在那時從數據庫中加載其內容,並跟蹤某些更改。 然后,Hibernate將在提交時保存更改。
由於您沒有讀取或更改address
字段,因此當Hibernate處理提交時,它會檢查PersistentMap
,發現它從未加載過,然后繼續忽略它,從而使那部分數據保持不變。
如果要清除address
數據,則需要明確地清除。 Hibernate嘗試避免意外更改數據,並且將從未加載的內容與刪除內容一樣對待很容易發生意外。
如果關閉會話,則Person實體將被分離。 當您調用saveOrUpdate()
,hibernate將把分離的對象重新附加到新的Session中。
為了執行延遲加載,Hibernate將Person包裹在擴展Person的代理類中。 初始化檢查在此代理中完成。 這意味着,如果您從未在第一個會話中訪問數據庫以獲取地址,則代理將知道這一點,並且當實體在第二個會話中重新連接時,它將把地址視為未初始化的地址,而不是將其從數據庫中刪除。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.