detached entity passed to persist 錯誤的引起的原因和解決辦法
阿新 • • 發佈:2019-02-01
今天在測試整合Spring和Hibernate的時候,遇到了一個問題,報錯情況如下:
報錯資訊:
org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.bean.Cat; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.bean.Cat
at org.springframework.orm .hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:668)
at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java :411)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.persist(HibernateTemplate.java:793)
at com.dao.impl.CatDaoImpl.createCat(CatDaoImpl.java:20)
at com.test.TestCat.testAdd (TestCat.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: com.bean.Cat
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:127)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:61)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:808)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:782)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:786)
at org.springframework.orm.hibernate3.HibernateTemplate$21.doInHibernate(HibernateTemplate.java:796)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
... 29 more
報錯原因:
從報錯資訊“detached entity passed to persist: com.bean.Cat”可以分析出,該錯誤是在Cat持久化轉換時出的錯。下面是測試的部分程式碼:
Cat實體類
/**
* @Author: zsh
* @Title: Cat.java
* @Description:Cat實體類
* @Date:2016年9月18日 下午3:12:23
*/
@Entity
@Table(name = "cat")
public class Cat {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(name = "name")
private String name;
@Temporal(value = TemporalType.TIMESTAMP)
private Date createDate;
……省略了構造器及setter、getter方法。
注意:使用註解的時候,為了避免破壞Java的封裝特性,一般會寫在get方法上,此處為了方便分析,所以寫在欄位上方。
測試方法
@Test
public void testAdd() throws ParseException{
Cat cat = new Cat(2,"TOM",new SimpleDateFormat("yyyy-MM-dd").parse("2000-1-1"));
cDao.createCat(cat);
}
通過分析兩段程式碼可以發現,在實體類中設定了ID欄位的自增,但是在測試時,例項化Cat類的時候又指定了ID的值,所以在執行的時候會報出錯誤!
解決方法:
1、取消欄位自增設定
2、例項化Cat物件時不設定ID值