-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Many-to-many, association tables, ConstraintViolation
PostPosted: Sat Aug 13, 2005 2:08 am 
Newbie

Joined: Tue Aug 02, 2005 4:53 pm
Posts: 14
Hibernate version:

3.0.5

Mapping documents:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   <class name="Principal" table="my_principal">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name" type="string">
            <column name="name" length="32" not-null="true" unique="true"/>
        </property>       
        <property name="description" type="string">
            <column name="description" length="1024"/>
        </property>
        <set name="groups" table="my_group_person" inverse="true">
            <key column="principal_id"/>
            <many-to-many class="Group" column="group_id"/>
        </set>

       <joined-subclass  name="Person" table="my_person">
           <key column="id"/>
            <property name="personID" type="string">
                <column name="person_id" length="32" unique="true" not-null="true"/>
            </property>
            <property name="userName" type="string">
                <column name="name" length="32" unique="true" not-null="true"/>
            </property>
            <property name="firstName" type="string">
                <column name="first_name" length="32" not-null="true"/>
            </property>
            <property name="middleName" type="string">
                <column name="middle_name" length="32"/>
            </property>
            <property name="lastName" type="string">
                <column name="last_name" length="32" not-null="true"/>
            </property>
            <property name="emailAddress" type="string">
                <column name="email_address" length="64"/>
            </property>
            <property name="primaryPhoneNumber" type="string">
                <column name="primary_phone_number" length="32" />
            </property>
            <property name="password" type="string">
                <column name="password" length="32"/>
            </property>
       </joined-subclass>
   
       <joined-subclass name="Group" table="my_group">
           <key column="id"/>
           <set name="members" table="my_group_person">
               <key column="group_id"/>
               <many-to-many class="Principal" column="principal_id"/>
           </set>
       </joined-subclass>
   </class>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():

GroupTest:

Code:
    public void testOne() {
        try {
            log.debug("creating a person");
            Person person1 = new Person();
            person1.setName("person 1");
            person1.setPersonID("7652845");
            person1.setFirstName("Person");
            person1.setLastName("1");
            personManager.createPerson(person1);

            Group group1 = new Group();
            group1.setName("group 1");
            groupManager.createGroup(group1);

            person1 = personManager.loadPerson("person 1");
            group1 = groupManager.loadGroup("group 1");

            group1.addMember(person1);
            groupManager.updateGroup(group1);

            person1 = (Person)personManager.loadPerson(person1.getId());
            log.debug("loaded parent: "+person1.getId());
            log.debug("name: "+person1.getName());

            Collection groups = person1.getGroups();
            Iterator i = groups.iterator();
            while (i.hasNext()) {
                Group cc = (Group)i.next();
                log.debug("  in group: "+cc.getName());
            }

            group1 = (Group)groupManager.loadGroup(group1.getId());
            log.debug("loaded child: "+person1.getId());
            log.debug("name: "+group1.getName());
            Collection members = group1.getMembers();
            i = members.iterator();
            while (i.hasNext()) {
                Person pp = (Person)i.next();
                log.debug("  member: "+pp.getName());
            }
        } catch (Exception e) {
            e.printStackTrace();
            fail("error");
        } catch (Error e) {
            e.printStackTrace();
            fail("error");
        }
    }

    public void testTwo() {
        try {
            log.debug("verifying person 1 exists");
            Person person1 = (Person)personManager.loadPerson("person 1");
            assertNotNull(person1);
            log.debug("loaded parent: "+person1.getId());
            log.debug("name: "+person1.getName());
            Collection groups = person1.getGroups();
            assertEquals(1, groups.size());
            Iterator i = groups.iterator();

            while (i.hasNext()) {
                Group cc = (Group)i.next();
                log.debug("  in group: "+cc.getName());
            }

            log.debug("deleting person");
{133}       personManager.deletePerson("person 1");
            log.debug("verifying that the person is gone, but the group remains with nothing in it");

            Group group1 = (Group)groupManager.loadGroup("group 1");
            assertNotNull(group1);

            log.debug("loaded child: "+group1.getId());
            log.debug("name: "+group1.getName());
            Collection members = group1.getMembers();
            assertEquals(0, members.size());

            i = members.iterator();
            while (i.hasNext()) {
                Person pp = (Person)i.next();
                log.debug("  member: "+pp.getName());
            }
        } catch (Exception e) {
            e.printStackTrace();
            fail("error");
        } catch (Error e) {
            e.printStackTrace();
            fail("error");
        }       
    }



Extending Spring HibernateDaoSupport and using inherited methods to create/update/delete. Simple persisters with nothing fancy. For example:
Code:
    public void createGroup(Group g) throws PersisterException {
        create(g);
    }

    public void updateGroup(Group g) throws PersisterException {
        update(g);
    }


Full stack trace of any exception that occurs:

Code:
GroupLoadException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
   at GroupManager.loadGroup(GroupManager.java:114)
   at GroupManager$$FastClassByCGLIB$$26c0884e.invoke(<generated>)
   at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
   at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:661)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:122)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:57)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
   at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:606)
   at GroupManager$$EnhancerByCGLIB$$fe30085b.loadGroup(<generated>)
   at GroupTest.testTwo(GroupTest.java:133)
   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:324)
   at junit.framework.TestCase.runTest(TestCase.java:154)
   at junit.framework.TestCase.runBare(TestCase.java:127)
   at junit.framework.TestResult$1.protect(TestResult.java:106)
   at junit.framework.TestResult.runProtected(TestResult.java:124)
   at junit.framework.TestResult.run(TestResult.java:109)
   at junit.framework.TestCase.run(TestCase.java:118)
   at junit.framework.TestSuite.runTest(TestSuite.java:208)
   at junit.framework.TestSuite.run(TestSuite.java:203)
   at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:325)
   at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.executeInVM(JUnitTask.java:848)
   at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.execute(JUnitTask.java:556)
   at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.execute(JUnitTask.java:532)
   at org.apache.tools.ant.Task.perform(Task.java:341)
   at org.apache.commons.jelly.tags.ant.AntTag.doTag(AntTag.java:185)
   at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:279)
   at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:135)
   at org.apache.commons.jelly.TagSupport.invokeBody(TagSupport.java:233)
   at org.apache.commons.jelly.tags.core.IfTag.doTag(IfTag.java:88)
   at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:279)
   at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:135)
   at org.apache.maven.jelly.tags.werkz.MavenGoalTag.runBodyTag(MavenGoalTag.java:79)
   at org.apache.maven.jelly.tags.werkz.MavenGoalTag$MavenGoalAction.performAction(MavenGoalTag.java:110)
   at com.werken.werkz.Goal.fire(Goal.java:639)
   at com.werken.werkz.Goal.attain(Goal.java:575)
   at com.werken.werkz.Goal.attainPrecursors(Goal.java:488)
   at com.werken.werkz.Goal.attain(Goal.java:573)
   at org.apache.maven.plugin.PluginManager.attainGoals(PluginManager.java:671)
   at org.apache.maven.MavenSession.attainGoals(MavenSession.java:263)
   at org.apache.maven.cli.App.doMain(App.java:488)
   at org.apache.maven.cli.App.main(App.java:1239)
   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:324)
   at com.werken.forehead.Forehead.run(Forehead.java:551)
   at com.werken.forehead.Forehead.main(Forehead.java:581)
Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:63)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:181)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:226)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:274)
   at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:48)
   at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:711)
   at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1315)
   at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:300)
   at com.logicalapps.persistence.hibernate.GenericHibernatePersister.loadByKey(GenericHibernatePersister.java:158)
   at GroupHibernatePersister.loadGroup(GroupHibernatePersister.java:49)
   at GroupManager.loadGroup(GroupManager.java:110)
   ... 49 more
Caused by: java.sql.BatchUpdateException: Batch entry 0 delete from my_principal where id=1 was aborted.  Call getNextException to see the cause.
   at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2392)
   at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1257)
   at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:334)
   at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2451)
   at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:294)
   at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:57)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:174)
   ... 59 more


Name and version of the database you are using:

PostgreSQL 8.0.3

The generated SQL (show_sql=true):

Code:
Hibernate: select nextval ('hibernate_sequence')
Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into my_principal (name, description, id) values (?, ?, ?)
Hibernate: insert into my_person (person_id, name, first_name, middle_name, last_name, email_address, primary_phone_number, password, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into my_principal (name, description, id) values (?, ?, ?)
Hibernate: insert into my_group (id) values (?)
Hibernate: select this_.id as id0_, this_1_.name as name0_0_, this_1_.description as descript3_0_0_, this_.person_id as person2_2_0_, this_.name as name2_0_, this_.first_name as first4_2_0_, this_.middle_name as middle5_2_0_, this_.last_name as last6_2_0_, this_.email_address as email7_2_0_, this_.primary_phone_number as primary8_2_0_, this_.password as password2_0_ from my_person this_ inner join my_principal this_1_ on this_.id=this_1_.id where this_1_.name=?
Hibernate: select this_.id as id0_, this_1_.name as name0_0_, this_1_.description as descript3_0_0_ from my_group this_ inner join my_principal this_1_ on this_.id=this_1_.id where this_1_.name=?
Hibernate: select this_.id as id0_, this_1_.name as name0_0_, this_1_.description as descript3_0_0_, this_.person_id as person2_2_0_, this_.name as name2_0_, this_.first_name as first4_2_0_, this_.middle_name as middle5_2_0_, this_.last_name as last6_2_0_, this_.email_address as email7_2_0_, this_.primary_phone_number as primary8_2_0_, this_.password as password2_0_ from my_person this_ inner join my_principal this_1_ on this_.id=this_1_.id where this_.id=?
Hibernate: select this_.id as id0_, this_1_.name as name0_0_, this_1_.description as descript3_0_0_ from my_group this_ inner join my_principal this_1_ on this_.id=this_1_.id where this_.id=?
Hibernate: insert into my_group_person (group_id, principal_id) values (?, ?)
Hibernate: select this_.id as id0_, this_1_.name as name0_0_, this_1_.description as descript3_0_0_, this_.person_id as person2_2_0_, this_.name as name2_0_, this_.first_name as first4_2_0_, this_.middle_name as middle5_2_0_, this_.last_name as last6_2_0_, this_.email_address as email7_2_0_, this_.primary_phone_number as primary8_2_0_, this_.password as password2_0_ from my_person this_ inner join my_principal this_1_ on this_.id=this_1_.id where this_1_.name=?
Hibernate: select groups0_.principal_id as principal1_1_, groups0_.group_id as group2_1_, group1_.id as id0_, group1_1_.name as name0_0_, group1_1_.description as descript3_0_0_ from my_group_person groups0_ inner join my_group group1_ on groups0_.group_id=group1_.id left outer join my_principal group1_1_ on group1_.id=group1_1_.id where groups0_.principal_id=?
Hibernate: select this_.id as id0_, this_1_.name as name0_0_, this_1_.description as descript3_0_0_, this_.person_id as person2_2_0_, this_.name as name2_0_, this_.first_name as first4_2_0_, this_.middle_name as middle5_2_0_, this_.last_name as last6_2_0_, this_.email_address as email7_2_0_, this_.primary_phone_number as primary8_2_0_, this_.password as password2_0_ from my_person this_ inner join my_principal this_1_ on this_.id=this_1_.id where this_1_.name=?
Hibernate: delete from my_person where id=?
Hibernate: delete from my_principal where id=?


Debug level Hibernate log excerpt:

Code:
java.sql.BatchUpdateException: Batch entry 0 delete from my_principal where id=1 was aborted.  Call getNextException to see the cause.
   at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2392)
   at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1257)
   at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:334)
   at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2451)
   at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:294)
   at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:57)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:174)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:226)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:274)
   at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:48)
   at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:711)
   at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1315)
   at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:300)
   at com.logicalapps.persistence.hibernate.GenericHibernatePersister.loadByKey(GenericHibernatePersister.java:158)
   at GroupHibernatePersister.loadGroup(GroupHibernatePersister.java:49)
   at GroupManager.loadGroup(GroupManager.java:110)
   at GroupManager$$FastClassByCGLIB$$26c0884e.invoke(<generated>)
   at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
   at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:661)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:122)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:57)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
   at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:606)
   at GroupManager$$EnhancerByCGLIB$$fe30085b.loadGroup(<generated>)
   at GroupTest.testTwo(GroupTest.java:133)
   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:324)
   at junit.framework.TestCase.runTest(TestCase.java:154)
   at junit.framework.TestCase.runBare(TestCase.java:127)
   at junit.framework.TestResult$1.protect(TestResult.java:106)
   at junit.framework.TestResult.runProtected(TestResult.java:124)
   at junit.framework.TestResult.run(TestResult.java:109)
   at junit.framework.TestCase.run(TestCase.java:118)
   at junit.framework.TestSuite.runTest(TestSuite.java:208)
   at junit.framework.TestSuite.run(TestSuite.java:203)
   at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:325)
   at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.executeInVM(JUnitTask.java:848)
   at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.execute(JUnitTask.java:556)
   at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.execute(JUnitTask.java:532)
   at org.apache.tools.ant.Task.perform(Task.java:341)
   at org.apache.commons.jelly.tags.ant.AntTag.doTag(AntTag.java:185)
   at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:279)
   at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:135)
   at org.apache.commons.jelly.TagSupport.invokeBody(TagSupport.java:233)
   at org.apache.commons.jelly.tags.core.IfTag.doTag(IfTag.java:88)
   at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:279)
   at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:135)
   at org.apache.maven.jelly.tags.werkz.MavenGoalTag.runBodyTag(MavenGoalTag.java:79)
   at org.apache.maven.jelly.tags.werkz.MavenGoalTag$MavenGoalAction.performAction(MavenGoalTag.java:110)
   at com.werken.werkz.Goal.fire(Goal.java:639)
   at com.werken.werkz.Goal.attain(Goal.java:575)
   at com.werken.werkz.Goal.attainPrecursors(Goal.java:488)
   at com.werken.werkz.Goal.attain(Goal.java:573)
   at org.apache.maven.plugin.PluginManager.attainGoals(PluginManager.java:671)
   at org.apache.maven.MavenSession.attainGoals(MavenSession.java:263)
   at org.apache.maven.cli.App.doMain(App.java:488)
   at org.apache.maven.cli.App.main(App.java:1239)
   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:324)
   at com.werken.forehead.Forehead.run(Forehead.java:551)
   at com.werken.forehead.Forehead.main(Forehead.java:581)
2005-08-12 22:29:30,518 WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: null
2005-08-12 22:29:30,518 ERROR org.hibernate.util.JDBCExceptionReporter - Batch entry 0 delete from my_principal where id=1 was aborted.  Call getNextException to see the cause.
2005-08-12 22:29:30,518 WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: 23503
2005-08-12 22:29:30,518 ERROR org.hibernate.util.JDBCExceptionReporter - ERROR: update or delete on "my_principal" violates foreign key constraint "fk752718c841b27ada" on "my_group_person"
2005-08-12 22:29:30,520 ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:63)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:181)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:226)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:274)
   at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:48)
   at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:711)
   at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1315)
   at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:300)
   at com.logicalapps.persistence.hibernate.GenericHibernatePersister.loadByKey(GenericHibernatePersister.java:158)
   at GroupHibernatePersister.loadGroup(GroupHibernatePersister.java:49)
   at GroupManager.loadGroup(GroupManager.java:110)
   at GroupManager$$FastClassByCGLIB$$26c0884e.invoke(<generated>)
   at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
   at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:661)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:122)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:57)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
   at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:606)
   at GroupManager$$EnhancerByCGLIB$$fe30085b.loadGroup(<generated>)
   at GroupTest.testTwo(GroupTest.java:133)
   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:324)
   at junit.framework.TestCase.runTest(TestCase.java:154)
   at junit.framework.TestCase.runBare(TestCase.java:127)
   at junit.framework.TestResult$1.protect(TestResult.java:106)
   at junit.framework.TestResult.runProtected(TestResult.java:124)
   at junit.framework.TestResult.run(TestResult.java:109)
   at junit.framework.TestCase.run(TestCase.java:118)
   at junit.framework.TestSuite.runTest(TestSuite.java:208)
   at junit.framework.TestSuite.run(TestSuite.java:203)
   at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:325)
   at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.executeInVM(JUnitTask.java:848)
   at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.execute(JUnitTask.java:556)
   at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.execute(JUnitTask.java:532)
   at org.apache.tools.ant.Task.perform(Task.java:341)
   at org.apache.commons.jelly.tags.ant.AntTag.doTag(AntTag.java:185)
   at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:279)
   at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:135)
   at org.apache.commons.jelly.TagSupport.invokeBody(TagSupport.java:233)
   at org.apache.commons.jelly.tags.core.IfTag.doTag(IfTag.java:88)
   at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:279)
   at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:135)
   at org.apache.maven.jelly.tags.werkz.MavenGoalTag.runBodyTag(MavenGoalTag.java:79)
   at org.apache.maven.jelly.tags.werkz.MavenGoalTag$MavenGoalAction.performAction(MavenGoalTag.java:110)
   at com.werken.werkz.Goal.fire(Goal.java:639)
   at com.werken.werkz.Goal.attain(Goal.java:575)
   at com.werken.werkz.Goal.attainPrecursors(Goal.java:488)
   at com.werken.werkz.Goal.attain(Goal.java:573)
   at org.apache.maven.plugin.PluginManager.attainGoals(PluginManager.java:671)
   at org.apache.maven.MavenSession.attainGoals(MavenSession.java:263)
   at org.apache.maven.cli.App.doMain(App.java:488)
   at org.apache.maven.cli.App.main(App.java:1239)
   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:324)
   at com.werken.forehead.Forehead.run(Forehead.java:551)
   at com.werken.forehead.Forehead.main(Forehead.java:581)
Caused by: java.sql.BatchUpdateException: Batch entry 0 delete from my_principal where id=1 was aborted.  Call getNextException to see the cause.
   at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2392)
   at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1257)
   at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:334)
   at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2451)
   at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:294)
   at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:57)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:174)
   ... 59 more



Now the error is exepected, because the person is being deleted and the association table entry that references it is not. My question is how do I get hibernate to remove association table entries when an associated object is deleted so that this doesn't occur? I assume that there is a way to map this correctly so that hibernate can handle the association removal, but I have not found an example that works yet. It would be preferable to not have to remove the associations, update the Group object, then delete it.

The create works fine, the association is created fine, Group objects can be loaded and members retrieved, Principal objects can be loaded and groups retrieved. Everything is fine until I try to remove a person object. I can avoid this error by adding code to remove the prinicpal from the group it is in before trying to remove it (on line 133) like:

Code:
            Group group1 = (Group)groupManager.loadGroup("group 1");
            group1.removeMember(person1);
            groupManager.updateGroup(group1);


Is that really what I need to do? Is there no way for hibernate to keep track of that association and remove the association table entries on the removal of an associated object?

I have tried different inverse settings, different cascade settings, etc. Can't cascading do the job of removing associations before removing the object? I had thought that a cascade setting of delete-orphan would do the trick (removing just the association when on of the associated objects was being removed), instead the object, association table entry *and* the other associated object are removed. That is not the behavior I am looking for either.

I have also tried to ensure that my classes correctly deal with the association collections:

Code:
Group:

    public void addMember(Principal p) {
        members.add(p);
        p.getGroups().add(this);
    }
   
    public void removeMember(Principal p) {
        members.remove(p);
        p.getGroups().remove(this);
    }

Principal:

    public Set getGroups() {
        return groups;
    }

    public void setGroups(Set groups) {
        this.groups = groups;
    }


Thanks in advance for any help.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Aug 13, 2005 12:53 pm 
Senior
Senior

Joined: Wed Jul 13, 2005 4:31 pm
Posts: 142
Location: Seattle, WA
Quote:
2005-08-12 22:29:30,518 ERROR org.hibernate.util.JDBCExceptionReporter - ERROR: update or delete on "my_principal" violates foreign key constraint "fk752718c841b27ada" on "my_group_person"


Looks like the my_group_person is the culprit...
Try, setting cascade on the set of groups -

Code:
<set name="groups" table="my_group_person" inverse="true" cascade="all-delete-orphan">
     <key column="principal_id"/>
     <many-to-many class="Group" column="group_id"/>
</set>


Top
 Profile  
 
 Post subject: Nope, not it
PostPosted: Sat Aug 13, 2005 6:09 pm 
Newbie

Joined: Tue Aug 02, 2005 4:53 pm
Posts: 14
Yeah, I have already tried different cascade settings on the groups collections. all-delete-orphan has the behavior of also deleting the associated object, not just the association.

Code:
Group1:
    Person1
    Person2

Group2:
   Person1:


If I delete Group1, I just want Group1 and the association table entries for Group1 -> Person1 and Group1 -> Person2 to be removed. The Person objects themselved should remain. Similarly, if I delete Person1 I want Person1 and the associations between Group1 -> Person1 and Group2 -> Person2 to be removed. The Group objects should remain.

As hibernate tracks these associations and manages the creation of association table entries, I've gotta imagine that it can remove the associations as well.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 14, 2005 12:47 am 
Newbie

Joined: Fri Aug 12, 2005 3:55 am
Posts: 11
It must work fine with cascade="update". But you must manualy delete associations from all connected objects. It may look like this.
Code:
public void deletePerson(Person p){
  for(Iterator it=p.getGroups().iterator();it.hasNext();)
    Group g=(Group)it.next;
    g.getPersons().remove(p);
  }
  hibernateSession.delete(p);
}

It's way needed only when a connected objects already loaded into the memory. But in most cases it's impossible to determine was they loaded or not without accesing to the collection.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 14, 2005 1:12 am 
Senior
Senior

Joined: Wed Jul 13, 2005 4:31 pm
Posts: 142
Location: Seattle, WA
Sorry, I missed that part.

Have you tried changing the inverse side of the relationship and cascading update, or all from that.

You still have to remove all the entries from groups.

Code:
<set name="groups" table="my_group_person" inverse="false" cascade="all">
     <key column="principal_id"/>
     <many-to-many class="Group" column="group_id"/>
</set>


and make the other side inverse -
Code:
<set name="members" table="my_group_person" inverse="true">
     <key column="group_id"/>
     <many-to-many class="Principal" column="principal_id"/>
</set>


and
remove all the elements from the groups set in person before saving.

I din't have time to try it out. Hope it helps.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 14, 2005 2:14 am 
Newbie

Joined: Tue Aug 02, 2005 4:53 pm
Posts: 14
Again, the cascade is going to delete the object on the other end of the association. I know that I can remove the associations manually ala:

Code:
    group1.removeMember(person1);
    groupManager.updateGroup(group1);


right before my

Code:
    personManager.deletePerson("person 1");


or I could of course put the code for removing associations within my manager (dao) to encapsulate it. But then hibernate isn't managing the associations...I am. I'm trying to figure out whether or not hibernate can only manage associations on create(), where it will save all associations to the associations table. What about on delete()? Hibernate obviously know about all the associations that are present, as it uses them for loading/updating/etc. I should be able to just remove an object and have hibernate remove association table references to that object, no?

Do I have to load the entire collection up from the DB and remove the associated objects, update the object and then delete? Even if it was that I had to remove the associated objects and the delete() would detect the association changes and remove association table entries...seems like hibernate has to be capable of this. So far the solutions I have seen that work involve removing associated objects and updating the object before it is deleted. Seems like hibernate should manage this for me and I just want to find out for sure whether or not hibernate will manage this for me. Maybe I am just asking for too much, heh. I just don't want to be handling it myself if there is a way to let hibernate do it for me.

How are others managing bi-directional many-to-many relationships and handling deletes?


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 14, 2005 2:25 am 
Newbie

Joined: Tue Aug 02, 2005 4:53 pm
Posts: 14
Oh, not to mention the fact that it gets to be a bigger issue with lots of associations. Imagine a person in 20 groups. Well since the group is managing the association and we want to remove a person, we have to load all 20 groups, remove the person from each and update each, then remove the person. In this example we also wanna be able to delete a group, which would be easier since it manages the association...remove all persons, update, delete.

We will probably need to perform both operations (delete of Person and Group). The side not managing the association is going to have a lot of work to do and probably won't scale very well. User's and groups aren't too big an issue performance-wise as they will change relatively infrequently, but it seems that other similar relationships could become problematic.

Cheers


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 26, 2005 2:05 pm 
Newbie

Joined: Fri Aug 26, 2005 1:45 pm
Posts: 1
I had a similar problem with a "Category-Item" type relationship, in which a deletion of one category would delete all it's subcategories, and the subcategories of those, and so on. I solved it by setting a OnDelete="Cascade" on the foreign key of the association table. Of course, this is not the answer you are looking for...


Top
 Profile  
 
 Post subject: Non-optimal solution
PostPosted: Fri Aug 26, 2005 7:14 pm 
Newbie

Joined: Tue Aug 02, 2005 4:53 pm
Posts: 14
I had to solve it by manually removing associations before trying to delete the object. So I add methods to Group called deleteAllMembers() and in the manager I do:

group.deleteAllMembers();
delete(group);

Not optimal IMO, as the relationships are already known by hibernate. I think hibernate should recognize that the group is being deleted and delete all associations to members that exist. The good news is that I don't have to call update() at all, as hibernate auot-detects that the collection has been updated and the associations are removed.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 04, 2005 8:44 am 
Newbie

Joined: Tue Aug 09, 2005 11:36 am
Posts: 3
I saw you use a PostgreSQL 8.0.3.

I had a similar problem with an Oracle Database and could solve it only within the Database. The Foreign Key Constraint, that links the attributes of the two tables must be defined as ON DELETE CASCADE.

Then only the association is deleted, not the referenced entry.

Hope that helps for Postgre, too ;)

_________________
The trick is not minding that it hurts


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 14, 2005 8:27 am 
Regular
Regular

Joined: Sat Sep 03, 2005 9:07 am
Posts: 87
Location: Graz, AUSTRIA
I have exactly the same problem.
I also only want to delete the association Table and the object of one table, but not the object of the other table
Can you tell me the exact Oracle Syntax and for which foreign key do I have to add the oracle Syntax?

Or the other way:
javcek where did you set the onDelete=cascade exactly?


THX!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 14, 2005 8:58 am 
Regular
Regular

Joined: Sat Sep 03, 2005 9:07 am
Posts: 87
Location: Graz, AUSTRIA
Solved!


Top
 Profile  
 
 Post subject:
PostPosted: Sun Apr 09, 2006 3:26 am 
Beginner
Beginner

Joined: Fri Jan 13, 2006 11:19 am
Posts: 24
Code:
<set table="user_in_role" lazy="true" inverse="true" cascade="none" name="users" >
      <key column="fk_user_role" on-delete="cascade"/>
      <many-to-many column="fk_user" class="com.usermgmt.vo.User" />
    </set>


I get the following error when after set on-delete="cascade"

Code:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [com/resources/daoContext.xml]: Initialization of bean failed; nested exception is org.hibernate.MappingException: only inverse one-to-many associations may use on-delete="cascade": com.usermgmt.vo.UserRole.users
     [exec] org.hibernate.MappingException: only inverse one-to-many associations may use on-delete="cascade": com.usermgmt.vo.UserRole.users
     [exec] at org.hibernate.mapping.Collection.validate(Collection.java:236)
     [exec] at org.hibernate.mapping.Set.validate(Set.java:19)
     [exec]


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 10, 2006 3:24 am 
Regular
Regular

Joined: Sat Sep 03, 2005 9:07 am
Posts: 87
Location: Graz, AUSTRIA
jimmy6 wrote:
Code:
<set table="user_in_role" lazy="true" inverse="true" cascade="none" name="users" >
      <key column="fk_user_role" on-delete="cascade"/>
      <many-to-many column="fk_user" class="com.usermgmt.vo.User" />
    </set>


I get the following error when after set on-delete="cascade"


I have never seen the on-delete="cascade" Attribute, but that doesn't mean that it's wrong.

Nevertheless, perhaps you try the following mapping (it's copied out of one of my projects... the cascade="all" and there isn't a on-delete attribute):

<set name="ewContactsMany" table="EW_PA2CON" lazy="true" inverse="true" cascade="all">
<key foreign-key="SYS_C0077258">
<column name="PA_ID" not-null="true"/>
</key>
<many-to-many entity-name="com.magnasteyr.editool.hibernate.workflow.EwContacts" foreign-key="SYS_C0077269">
<column name="CON_ID" not-null="true"/>
</many-to-many>
</set>


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 11, 2006 5:15 am 
Beginner
Beginner

Joined: Fri Jan 13, 2006 11:19 am
Posts: 24
user -userinrole - userrole

I had try cascade=all but hibernate will delete all the user as well when i delete the userrole. I just want to delete the userrole and the relationship in userinrole table only.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.