[英]save working but persist not working in hibernate 4.1.1
我試圖保存數據usged hsqldb我正在使用hibernate 4.1.4.Final。 我的問題是我想使用持久保存數據,但是當我嘗試這樣做時,它顯示以下錯誤:
org.hibernate.PersistentObjectException: detached entity passed to persist: main.java.entity.Advocate
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:141)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:835)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:828)
at org.hibernate.engine.spi.CascadingAction$7.cascade(CascadingAction.java:315)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:423)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:264)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:126)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:78)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:844)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:819)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:823)
at main.java.service.LegalService.registerCase(LegalService.java:46)
at main.java.tester.Tester.registerCase(Tester.java:52)
at main.java.tester.Tester.main(Tester.java:28)
但是當我使用保存方法時它起作用了,所以我想知道持久性和保存有何不同? 和我的實體類已序列化。如何解決此持久性錯誤。
這是我的課
package main.java.service;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import main.java.businessTier.CaseTO;
import main.java.entity.Advocate;
import main.java.entity.Case;
public class LegalService {
Configuration configuration = new Configuration().configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(
configuration.getProperties()). buildServiceRegistry();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
public int registerCase(CaseTO caseTO) {
try
{
Session session;
session=sessionFactory.openSession();
session.beginTransaction();
Case c = new Case();
Advocate a = new Advocate();
a.setAdvocateId(caseTO.getAdvocateId());
c.setAdvocate(a);
c.setClientAge(caseTO.getClientAge());
c.setClientName(caseTO.getClientName());
c.setDate(caseTO.getDate());
c.setDescription(caseTO.getDescription());
session.persist(c);
session.getTransaction().commit();
return c.getCaseNo();
}
catch(Exception e){
e.printStackTrace();
return 0;
}
}
}
這是我的實體類Advocate.java
package main.java.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
@Entity
@Table(name="Db_Advocate")
@DynamicInsert(value=true)
@DynamicUpdate(value=true)
public class Advocate {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="advocateId")
private Integer advocateId;
@Column(name="name")
private String name;
@Column(name="age")
private Integer age;
@Column(name="category")
private String category;
@Column(name="court")
private String court;
@Column(name="city")
private String city;
public Integer getAdvocateId() {
return advocateId;
}
public void setAdvocateId(Integer advocateId) {
this.advocateId = advocateId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getCourt() {
return court;
}
public void setCourt(String court) {
this.court = court;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
Case.java
package main.java.entity;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
@Entity
@Table(name="DB_CASE")
@DynamicInsert(value=true)
@DynamicUpdate(value=true)
public class Case {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer caseNo;
@JoinColumn(name="advocateId")
@ManyToOne(cascade=CascadeType.ALL)
private Advocate advocate;
private String clientName;
private Integer clientAge;
private String description;
private Date date;
public Integer getCaseNo() {
return caseNo;
}
@Column(name="caseNo")
public void setCaseNo(Integer caseNo) {
this.caseNo = caseNo;
}
public Advocate getAdvocate() {
return advocate;
}
public void setAdvocate(Advocate advocateId) {
this.advocate = advocateId;
}
public String getClientName() {
return clientName;
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
public Integer getClientAge() {
return clientAge;
}
public void setClientAge(Integer clientAge) {
this.clientAge = clientAge;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getDate() {
return date;
}
@Column(name="data",nullable=true)
public void setDate(Date date) {
this.date = date;
}
}
請在id處添加以下代碼
@Id @GeneratedValue(strategy = GenerationType.AUTO)
然后堅持會起作用
首先,您需要了解persist()的行為。 以下是可以幫助您了解行為的鏈接: Hibernate中的persist()和save()之間有什么區別? http://javarevisited.blogspot.in/2012/09/difference-hibernate-save-vs-persist-and-saveOrUpdate.html
現在為了在你的代碼中解決這個問題..使用merge()而不是persist()。
為什么persist()給出了異常
persist()對分離的對象不起作用。您需要知道休眠是如何確定對象是否分離的。
UPDATE
為什么標識符生成策略會自動解決您的問題
正如我上面提到的,您需要了解休眠標識對象是分離的還是瞬態的規則。 以下是規則
如果實體的標識符值為null或version屬性為null,則將其視為瞬態(否則)分離。
如果使用自動生成的標識符,並且標識符不為null,則Hibernate會將其視為獨立實體。
如果您使用的是已分配的標識符策略,那么hibernate將發出一個提取,以確定該標識符是否存在於db中,因為您的實體將是瞬態或分離的。
現在說..我們分析你的代碼。
在您的代碼中,您有Advocate實體,其標識符策略為IDENTITY。在下面的代碼中
Case c = new Case();
Advocate a = new Advocate();
a.setAdvocateId(caseTO.getAdvocateId());
您正在手動設置Advocate實例的標識符屬性。在事務提交時刷新的時間,hibernate將看到標識符生成策略為IDENTITY,並且在提供者實例中設置標識符值,因此它將斷定實體實例已分離(這來自上面描述的規則1)。因此,persist()方法為propate實例提供了異常,因為它被認為與hibernate分離。
從規則2我們可以說,只需將生成策略更改為auto,您的代碼就無法工作。您可能已經做了一些其他更改。
我已經在我的系統上嘗試過你的代碼,即使我將生成策略更改為auto,這也符合規則
您可能在代碼中執行了不同的操作..請檢查並更新。
還請發布您在倡導者中設置的標識符以及使用自動生成策略在數據庫中為該擁護者生成的實際標識符,這可能會有所幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.