今天在测试整合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值