Possible Duplicate:
Hibernate and Spring - entity with multiple members inheriting from same parent causes JDBCException, @Transactional weirdness
I have reformated this question into SSCCE - See the reformatted question
I m having a problem with my spring webmvc project, which uses Hibernate via JPA. The application models college courses, students, assignments, announcements, and students comments on those assignments and announcements (and much more, but these are the relevant entities for this question)
实体:
@Entity
public class Section {
@Id
@GeneratedValue
long id;
@OneToMany(cascade = CascadeType.ALL)
private Set<Assignment> assignments = new HashSet<Assignment>();
@OneToMany(cascade = CascadeType.ALL)
private Set<Announcement> announcements = new HashSet<Announcement>();
... more properties, getters/setters, etc ...
转让和通知共用一个基础类别,只有自动生成的Id。 问题在于,当我试图在交易方法中设立一个章节和一项转让时,我获得一个org.hibernate. Union.GenericJDBCException: 不能执行亚洲开发银行的最新批量“除外。
试验情况如下:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath*:WEB-INF/spring-data.xml")
public class EntityPersistenceTest {
@PersistenceContext
EntityManager entityManager;
@Autowired
SectionService sectionService;
@Autowired
DbTestData dbTestData;
@Test
public void Test() {
dbTestData.persistTestData();
}
@After
public void afterTest() {
Section art = sectionService.byCourseSchoolIdYearSeason("art101", 2011, Semester.Season.fall);
Assert.assertTrue(art.getAssignments().size() > 0);
Assert.assertTrue(art.getAnnouncements().size() > 0);
System.out.println("Test completed successfully.");
}
}
这里持续存在 Db.Data(与部件附加说明)的测试数据
@Transactional
public void persistTestData(){
Course art = new Course("art101", "Art 101 - Basic Art", "General art class focusing on finger painting");
Professor ron = new Professor("Ron", "Bier", "ron@school.edu", "ron", "password");
Semester fall11 = new Semester(2011, Semester.Season.fall);
Section section = new Section(art, fall11, "51024");
entityManager.persist(art);
entityManager.persist(ron);
entityManager.persist(fall11);
entityManager.persist(section);
Date sevenDaysAway = new Date(System.currentTimeMillis() + (1000 * 60 * 60 * 24 * 7));
section.addAssignment(new Homework(ron, new Date(), sevenDaysAway, true, "Art project 1"));
section.addAnnouncement(new Announcement(ron, new Date(), "Announcement Text"));
}
这里是排气和错误代码的全方位缩水记录,在发出呼吁时发生。 测试数据:
Hibernate: insert into Course (id, description, schoolId, title) values (null, ?, ?, ?)
Hibernate: call identity()
Hibernate: insert into Person (id, email, enabled, first, last, passwordHash, username, DTYPE) values (null, ?, ?, ?, ?, ?, ?, Professor )
Hibernate: call identity()
Hibernate: insert into Semester (id, season, year) values (null, ?, ?)
Hibernate: call identity()
Hibernate: insert into Section (id, active, course_id, sectionId, semester_id) values (null, ?, ?, ?, ?)
Hibernate: call identity()
DEBUG: com.whiteboard.wb.data.entity.Assignment - Created a new Assignment with params
Hibernate: insert into Commentable (id, author_id, postDate, active, due, abstrct, DTYPE) values (null, ?, ?, ?, ?, ?, Homework )
Hibernate: call identity()
Hibernate: insert into Person_authorities (Person_id, authorities) values (?, ?)
Hibernate: insert into Section_Commentable (Section_id, assignments_id) values (?, ?)
WARN : org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: null
ERROR: org.hibernate.util.JDBCExceptionReporter - failed batch
ERROR: org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:128)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:262)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:182)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:375)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:76)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:467)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
at com.whiteboard.wb.data.sample.DbTestData$$EnhancerByCGLIB$$ca8fb7f2.persist(<generated>)
at entity.BigTest.Test(BigTest.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:71)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:199)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.sql.BatchUpdateException: failed batch
at org.hsqldb.jdbc.jdbcStatement.executeBatch(Unknown Source)
at org.hsqldb.jdbc.jdbcPreparedStatement.executeBatch(Unknown Source)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 49 more
我找到了解决该问题的三种办法,我完全不理解:
只有一个项目可在该科实体内提出意见。 删除从科收集的“年度”单原子(以及从测试中向科发出的呼吁)使这一错误完全消失。 显然,我需要收集多种不同类型的评论材料,因此是不可接受的。
Annotate the @Test call with @Transactional. With identical code everywhere else, this completely fixes the problem, and both the Announcement and Homework get persisted correctly without errors.
@Test @Transactional public void Test() { dbTestData.persist(); }
在不同的交易中加上转让和通知,而不是在设立这一节时。 如果我以“()试验”方法添加“转让”和“通知”,所有查询都圆满完成。 但是,由于CascadeType = CascadeType.all在该科实体的藏书上,我看不出为什么应该这样做。
I am pretty new to ORM, and have been trying to understand what is going on here for a while now so I am hoping someone with more experience can help me out. The fact that annotating the Test method with @Transactional fixes it makes me think that the tables Hibernate is generating can handle this situation of having multiple collections of entities that extend the same abstract class, but then it means that I don t understand what @Transactional means which worries me. (I have set Hibernate to automatically generate all required tables in my Spring config file using <property name="generateDdl" value="true"/>
on my vendor adapter bean)
Thanks for the help. Sorry this question got so long for what will probably be a 2 line answer.
让我知道,你们是否需要我的其他法典。