2017-04-18 78 views
1

根據here只要我使用org.hibernate.Session,而不是JPA,應該允許它使用session.remove(entity)休眠脫離實體錯誤而刪除的實體

但是每當我試圖刪除實體刪除也是分離的實體,它不允許我因分離狀態而將其刪除。

這條線是這樣的;

employeeDao.delete(employee) 

即使我嘗試刪除這樣

employeeDao.delete(employeeDao.findById(employee.getId)): 

它給出了同樣的錯誤,並且不會將其刪除。

例外的是

意外的RuntimeException 最後原因:刪除脫管的實例rd.core.model.Employee#69

堆棧跟蹤爲

根原因:

java.lang.IllegalArgumentException:卸下分離的情況下 rd.core.model.Employee#69 在org.hibernate.jpa.event.internal.core.JpaDeleteEventListener.performDetachedEntityDeletionCheck(JpaDeleteEventListener.java:69) 在org.hibernate.event.internal.DefaultDeleteEventListener。 onDelete(DefaultDeleteEventListener.java:106) 在org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:73) 在org.hibernate.internal.SessionImpl.fireDelete(SessionImpl.java:920) 在有機hibernate.internal.SessionImpl.delete(SessionImpl.java:896) 在rd.core.persistence.AbstractHibernateDao.delete(AbstractHibernateDao.java:35) 在rd.core.services.EmployeeManagerImpl.deleteEmployee(EmployeeManagerImpl.java:186) at c om.google.inject.persist.jpa.JpaLocalTxnInterceptor.invoke(JpaLocalTxnInterceptor.java:66) 在java.lang.reflect.Method.invoke(Method.java:606)

我想我搞亂完全錯誤的東西。即使這會導致相同的例外。

public void remove(Employee employee) { 
     getCurrentSession().merge(employee); 
     getCurrentSession().delete(employee); 
    } 

這裏是我的POJO

@Entity 
@Table(name = "TMP_EMPLOYEE") 
public class Employee implements Identifiable<Integer> { 

private static final String ID_GENERATOR_NAME = "TMP_EMPLOYEE_ID_SEQ"; 
public static final String PROP_FULL_NAME = "fullName"; 
public static final String PROP_ID = "id"; 
public static final String PROP_DEP = "department"; 

public static final String COLUMN_FULL_NAME = "FULL_NAME"; 
public static final String COLUMN_ID = "emp.ID"; 
public static final String COLUMN_DEP = "NAME"; 

@Column(name = "ID", nullable = false) 
@Id 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = ID_GENERATOR_NAME) 
@SequenceGenerator(name = ID_GENERATOR_NAME, sequenceName = "S_EMPLOYEE_ID", allocationSize = 1) 
private Integer id; 

@Column(name = "FULL_NAME", nullable = false, length = 60) 
@Basic 
private String fullName; 

@ManyToOne 
@JoinColumn(name = "DEP_ID", referencedColumnName ="ID", nullable = false) 
@Fetch(FetchMode.SELECT) 
private Department department; 

public Integer getId() { 
    return id; 
} 

public void setId(Integer id) { 
    this.id = id; 
} 

public String getFullName() { 
    return fullName; 
} 

public void setFullName(String fullName) { 
    this.fullName = fullName; 
} 

public Integer getDepartmentId() { 
    return 0; 
} 

public void setDepartmentId(Integer departmentId) { 

} 

@Override 
public boolean equals(Object o) { 
    if (this == o) 
     return true; 
    if (!(o instanceof Employee)) 
     return false; 

    Employee that = (Employee) o; 

    if (getId() != null ? !getId().equals(that.getId()) : that.getId() != null) 
     return false; 

    return true; 
} 

@Override 
public int hashCode() { 
    return getId() != null ? getId().hashCode() : 0; 
} 

@Override 
public Integer getIdentity() { 
    return id; 
} 

@Override 
public String toString(){ 
    return "Id: " + this.id + " Employee Name: " + this.fullName; 
} 

public Department getDepartment() { 
    return department; 
} 

public void setDepartment(Department department) { 
    this.department = department; 
} 

這聽起來可能很簡單,但什麼原因導致究竟改變實體狀態這樣,爲什麼我不能刪除它,即使它被分離?

注意:我正在通過類委託相同的員工實例。所以它總是同一個實體。

如果您需要更多數據,請諮詢。實際上我不知道哪些數據可以幫助我們弄清楚這一點。

+0

什麼是錯誤? – ProgrammerBoy

+0

如果hibernate告訴你你的實體已經分離,只需在刪除它之前重新附加它。 – Zorglube

+0

顯示你的pojo請 –

回答

1

您可以閱讀關於「why can't I remove it even if it is detached」,那裏你可以找到這樣的:

需要注意的是Hibernate的本身可以處理刪除 分離狀態是很重要的。然而,JPA不允許它。這裏的含義是 ,該實體實例傳遞給org.hibernate.Session刪除 方法可以處於託管狀態或分離狀態,而實體 傳遞給javax.persistence.EntityManager的實例必須在託管狀態下爲 。

關於爲什麼這個對象在您之後分離,find它,我們不知道它或者沒有看到代碼。但是您可以在上面的同一篇文章中閱讀它,以瞭解實體如何分離以及如何重新連接它在部分3.8。使用分離的數據

在你應該不做什麼來防止物體的超脫摘要:

  1. 關閉持久化上下文
  2. 清除持久化上下文
  3. 從持久化上下文驅逐特定實體
  4. 對象序列化(反序列化對象將被分離,序列化對象不總是)

但是如果你不能阻止,你應該使用Session.saveOrUpdate(),Session.update()或Session.merge()之類的東西重新連接對象。或者..簡單地使用hibernate(不是JPA)Session.delete()。

+0

你說得對。在find方法中,我使用查詢而不是使用session.get。因此它正在關閉持久化上下文並打開另一個上下文環境。我想這是事情? –

0

這是Hibernate的實體生命週期。所以session.update應該做的是重新連接分離的實體。但是,更新可能會導致一些錯誤,所以我發現人們通常使用合併來重新連接實體。

enter image description here

所以,如果你懶洋洋地初始化實體可能有關。

當Hibernate從數據庫中讀取數據時,數據保存在 會話中。您可以保存對數據的引用 - 例如,在您的 HTTP請求中。一旦交易提交併且會話關閉了 ,則無法使用此會話加載任何其他數據。休眠 只加載第一個對象並用代理替換其他對象集合 。如果您訪問代理,Hibernate使用當前的會話來初始化代理並加載 數據庫中的條目。

就我所知,您正在使用Open-Session-in-View模式。所以請嘗試閱讀這些材料。

Lazy Initialization

Open Session In View

問題可能是由於多種原因造成的,所以它是你爲了什麼做什麼真的很重要。