我正在尝试使用hsnate 4.1.4.Final来保存数据。我的问题是我想使用persist保存数据但是当我尝试这样做时显示以下错误:
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;
}
}
答案 0 :(得分:0)
请在ID
添加以下代码@Id @GeneratedValue(strategy = GenerationType.AUTO)
然后坚持将起作用
答案 1 :(得分:0)
首先,您需要了解persist()的行为。 以下链接将帮助您了解行为 Whats the difference between persist() and save() in Hibernate? http://javarevisited.blogspot.in/2012/09/difference-hibernate-save-vs-persist-and-saveOrUpdate.html
现在为了解决代码中的这个问题,请使用merge()而不是persist()。
为什么persist()给出异常
persist()不适用于分离的对象。您需要知道hibernate如何确定对象是否已分离。
<强>更新强>
为什么标识符生成策略会自动解决您的问题
正如我上面提到的,您需要了解hibernate识别对象是分离还是瞬态的规则。以下是规则
如果实体的标识符为空值,或者版本属性为null,则将其视为瞬态其他明智的分离。
如果您使用自动生成的标识符,并且标识符不为null,则Hibernate会将其视为已分离的实体。
如果您使用的是已分配的标识符策略,则hibernate将发出一个提取,以确定该标识符是否存在于db中,具体取决于您的实体将是瞬态还是分离。
现在说...我们分析你的代码。
在您的代码中,您拥有其标识符策略为IDENTITY的Advocate实体。在以下代码中
Case c = new Case();
Advocate a = new Advocate();
a.setAdvocateId(caseTO.getAdvocateId());
您正在手动设置Advocate实例的标识符属性。在事务提交时刷新的时间,hibernate将看到标识符生成策略是IDENTITY并且在提供者实例中设置标识符值因此它将得出结论实体实例是分离的(这是上面描述的规则1)。因此,persist()方法为拥护实例提供了异常,因为它被认为与hibernate分离。
从规则2我们可以说,只需将生成策略更改为auto,您的代码就无法工作。您可能已经做了一些其他更改。
我已经在我的系统上尝试过你的代码,即使我将生成策略更改为与规则一致的auto,也会给出相同的异常
您可能在代码中执行了不同的操作..请检查并更新。
还请发布您在倡导者中设置的标识符以及使用自动生成策略在数据库中为该拥护者生成的实际标识符,这可能会有所帮助