Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6721335
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T09:19:05+00:00 2026-05-26T09:19:05+00:00

(This is a rewrite of my other question ) I have a Spring WebMVC

  • 0

(This is a rewrite of my other question)

I have a Spring WebMVC app that uses Hibernate as its backend. Since my domain model is changing constantly and I am not using a legacy database as a backend, I set Hibernate to auto-generate tables every time I start my application by setting <property name="generateDdl" value="true"/> in my spring config.

The problem comes from one of my entities having two one-to-many relationships to entity types that share the same parent class. Here are very basic versions of my classes that still show the problem:

@Entity
public abstract class Base {
    @Id
    @GeneratedValue
    private long id;
}


@Entity
public class ChildTypeA extends Base{

}

@Entity
public class ChildTypeB extends Base{

}




@Entity
public class Container {

    @Id
    @GeneratedValue
    private long id;

    @OneToMany(cascade = CascadeType.ALL)
    Set<ChildTypeA> childrenA = new HashSet<ChildTypeA> ();

    @OneToMany(cascade = CascadeType.ALL)
    Set<ChildTypeB> childrenB = new HashSet<ChildTypeB>();

    public void addChildA(ChildTypeA child){
        childrenA.add(child);
    }
    public void addChildB(ChildTypeB child){
        childrenB.add(child);
    }
}

Running the below test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath*:WEB-INF/spring-data.xml")
public class NewTest {

    @Autowired
    DataGenerator dataGenerator;

    @Test
    //@Transactional
    public void test(){
        dataGenerator.generateTestData();
    }
}




@Component
public class DataGenerator {
    @PersistenceContext
    EntityManager em;

    @Transactional
    public void generateTestData(){
        Container c = new Container();
        c.addChildA(new ChildTypeA());
        em.persist(c);
    }
}

gives me the following log:

Hibernate: insert into Base (id, DTYPE) values (null, 'ChildTypeA')
Hibernate: call identity()
Hibernate: insert into Container (id) values (null)
Hibernate: call identity()
Hibernate: insert into Container_Base (Container_id, childrenA_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.DataGenerator$$EnhancerByCGLIB$$5c355801.generateTestData(<generated>)
    at entity.NewTest.test(NewTest.java:39)
    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
Hibernate: select container0_.id as id3_ from Container container0_

org.springframework.orm.hibernate3.HibernateJdbcException: JDBC exception on Hibernate data access: SQLException for SQL [insert into Container_Base (Container_id, childrenA_id) values (?, ?)]; SQL state [null]; error code [0]; Could not execute JDBC batch update; nested exception is org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:645)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:102)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:471)
    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.DataGenerator$$EnhancerByCGLIB$$5c355801.generateTestData(<generated>)
    at entity.NewTest.test(NewTest.java:39)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: 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)
    ... 40 more
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

However, if I wrap the @Test method in @Transactional, the error goes away and both the container and the child are successfully persisted.
Also, if I remove the OneToMany with ChildTypeB and have only the relationship with ChildTypeA, both the container and the child are sucecssfully persisted.

Is this a bug with Spring’s Application Managed persistence? Or am I understanding @Transactional wrong? Or, do I need to tell Hibernate to separate the children into different tables, either through an annotation on the relationship or on the classes themselves?

Thanks for the help.

Edit:

Adding my Persistence.xml and spring-data.xml

Persistence.xml (all the real work is done in spring-data.xml):

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="spring-jpa" />
</persistence>

spring-data.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
        http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- Scans the classpath of this application for @Components to deploy as beans -->
    <context:component-scan base-package="com.whiteboard.wb"/>
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="persistenceUnitName" value="spring-jpa"/>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="true"/>
                <property name="generateDdl" value="true"/>
                <property name="database" value="HSQL"/>
            </bean>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>

    <jdbc:embedded-database id="dataSource" type="HSQL"/>

</beans>
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T09:19:06+00:00Added an answer on May 26, 2026 at 9:19 am

    There’s only one problem with that: Base should be annotated with @MappedSuperClass instead of @Entity. After that–and supplying a pom–it works fine, either with or without @Transactional on the test method. I put it on github. You can browse it or clone and run it with

    git clone git://github.com/zzantozz/testbed tmp
    cd tmp
    mvn clean test -pl stackoverflow/7809543-hibernate-spring-jpa
    

    I think in distilling it, you cut out what was causing the problem. Sometimes when you’re just completely lost, it’s helpful to make a branch of your project (if you’re in git) or a copy of it in a separate directory (if you’re burdened with SVN) and start hacking out the stuff that isn’t problematic until you can get it down to exactly the code/configuration that’s causing the problem.

    Update: Understanding dawns. First issue: the reason it behaves differently depending on whether the test is @Transactional or not is that your test transaction is different from your DataGenerator transaction. In the test, the transaction is rolled back at the end of the test. In DataGenerator, it’s committed. More importantly the EntityManager isn’t flushed in the test because that typically only happens at commit time. flush() is what causes SQL to be issued to the database, and that’s where your error is coming from. If you inject your test with an EntityManager and call flush() on it at the end of the test method, then you’ll see the same behavior in your @Transactional test as what you’re seeing in your non-@Transactional one now. This is pretty standard fare for tests when you’re doing transaction rollbacks to keep your db clean.

    Second issue: Because Base is an entity and not just a superclass containing some common fields like I initially thought, you’re dealing with inheritance mapping. (Annotation-based inheritance is covered in the separate Hibernate Annotations reference.) Whether you realized it or not, you’ve implicitly chosen the “single table” inheritance strategy. It’s the JPA default for mapping inheritance, for better or worse. That means that all fields of Base, ChildTypeA, and ChildTypeB are contained in the Base table. If you turn logging down to debug, you’ll see that Hibernate is generating this table structure:

    create table Base (DTYPE varchar(31) not null, id bigint generated by default as identity (start with 1), primary key (id))
    create table Container (id bigint generated by default as identity (start with 1), primary key (id))
    create table Container_Base (Container_id bigint not null, childrenB_id bigint not null, childrenA_id bigint not null, primary key (Container_id, childrenA_id), unique (childrenB_id), unique (childrenA_id))
    

    Your trouble is coming from Container_Base. If you look carefully, you’ll see that an entry in that table is required to have both a ChildTypeA primary key and a ChildTypeB primary key. This doesn’t accurately reflect your object model, where they’re two, unrelated collections. I’m not sure why Hibernate is doing that. My guess is that it just sees two (implicit) join table mappings–that’s the two join tables for your one-to-many relationships–that have the same table name and combines them together. This looks like a candidate for a bug report to me. Anyway, there are at least two ways to solve this:

    1. Switch to the table-per-class inheritance strategy by adding @Inheritance(strategy = InheritanceType.JOINED) to Base. This will create separate tables for Base, ChildTypeA, and ChildTypeB. Then the join tables will sort themselves out on their own because there’s no ambiguity.
    2. Explicitly name the join tables in your mappings on Container using, e.g., @JoinTable(name = "containerChildA") and @JoinTable(name = "containerChildB") as appropriate. This will create the two separate join tables you need but leave Base, ChildTypeA, and ChildTypeB all living in the same table.
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I hope this is not a very stupid question. I have to rewrite the
I have a Flash app that uses an implementation of SWF Address for deep
This might be a really rookie question, but I'm writing an Android app that
i have a question for you. I have a component that have 2 methods.
I know that this is not the first time a question about this issue
I'm pretty sure that this is the right site for this question, but feel
This question is related to this other question: Change rails text_field form builder type
I realize this question is the reverse of most of this sort. In other
I have this problem that I need to solve for one of my projects.
I had a look at a few possible duplicates for this question but rewrite

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.