-->
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.  [ 1 post ] 
Author Message
 Post subject: Incomplete Rollback with 1-1 Association and Spring and JTA
PostPosted: Tue Oct 24, 2006 12:49 pm 
Newbie

Joined: Tue Oct 24, 2006 12:23 pm
Posts: 1
Hi,

maybe this is a newbe-question, thus I would first like to show the application code.

I do have a Person-Class which is associated with a 1-1 mapping to a Adress class. I have a service method to create a Person-object.

Code:
void createPerson() {
    springHibernateTemplate.save(person);
    if (isInvalid(person))
      throw Exception(); // and cause a rollback
}


Now my problem is this:



The first time createPerson() is called with an invalid person.

The transaction is rolled back.

The next time createPerson() is called with a valid person. It is the same object with different properties.

Now the transaction commits. But Hibernate only tries to create a new Person-object and not a corresponding Adress-object.

This is the debug output for the Insert:
Code:
DEBUG - AbstractFlushingEventListener.flushEverythingToExecutions(85) | Flushed: 1 insertions, 1 updates, 0 deletions to 2 objects
Hibernate: insert into PERSONEN (nachname, vorname, adresse, ID) values (?, ?, ?, ?)

And this is the error:
Code:
DEBUG - JDBCExceptionReporter.logExceptions(63) | could not insert: [de.akquinet.spring.kundenverwaltung.db.Kunde] [insert into PERSONEN (nachname, vorname, adresse, ID) values (?, ?, ?, ?)]
ERROR 23503: INSERT on table 'PERSONEN' caused a violation of foreign key constraint 'FK491016BE65BE6C18' for key (1081344).  The statement has been rolled back.


To me it seems that in the first call Hibernate marked the adress object as saved. I could see in the debugger that the id is set. In the second call Hibernate tries to create the Person with a non existing Adress-ID.

Do I something wrong?

-- Torsten


Hibernate version:
3.1

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="de.akquinet.spring.kundenverwaltung.db.Adresse"
         table="ADRESSEN">
      <id name="id" column="ID" access="field">
         <generator class="native"/>
      </id>
      <property name="stadt">
         <column name="STADT" sql-type="VARCHAR(30)"/>
      </property>
      <component name="postleitzahl">
         <property name="postleitzahl" access="field">
            <column name="PLZ" sql-type="CHAR(5)"/>
         </property>
      </component>
      <component name="strasseHausnummer">
         <property name="strasse">
            <column name="STRASSE" sql-type="VARCHAR(30)"/>
         </property>
         <property name="hausnummer">
            <column name="HAUSNR" sql-type="VARCHAR(10)"/>
         </property>
      </component>
   </class>
</hibernate-mapping>

<?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>
   <joined-subclass name="de.akquinet.spring.kundenverwaltung.db.Kunde"
            extends="de.akquinet.spring.kundenverwaltung.db.Person"
            table="KUNDEN">
      <key column="ID"/>
      <property name="kundennummer"/>
   </joined-subclass>
</hibernate-mapping>

<?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="de.akquinet.spring.kundenverwaltung.db.Person"
      table="PERSONEN" abstract="true">
      <id name="id" column="ID" access="field">
         <generator class="native" />
      </id>
      <property name="nachname" />
      <property name="vorname" />
      <!-- 1-1 erfordert gleiche IDs, Adressen können aber auch von anderen Personen benutzt werden unique="true"-->
      <many-to-one name="adresse" cascade="all"
         access="field" lazy="false" not-null="true"/>
   </class>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():
Code:
   public void createKunde(final Kunde neuerKundePrototyp)
         throws NameSchonVorhandenException {
      
      hibernateTemplate.save(neuerKundePrototyp);
      
      if (isValid(neuerKundePrototyp)) {
         throw new NameSchonVorhandenException();
      }
   }

Full stack trace of any exception that occurs:
Code:
DEBUG - AbstractFlushingEventListener.prepareCollectionFlushes(153) | dirty checking collections
DEBUG - AbstractFlushingEventListener.flushEverythingToExecutions(85) | Flushed: 1 insertions, 1 updates, 0 deletions to 2 objects
Hibernate: insert into PERSONEN (nachname, vorname, adresse, ID) values (?, ?, ?, ?)
DEBUG - AbstractFlushingEventListener.flushEverythingToExecutions(91) | Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
DEBUG - Printer.toString(83) | listing entities:
DEBUG - Printer.toString(90) | de.akquinet.spring.kundenverwaltung.db.Adresse{postleitzahl=component[postleitzahl]{postleitzahl=13245}, stadt=ad, strasseHausnummer=component[strasse,hausnummer]{strasse=str, hausnummer=56}, id=1081344}
DEBUG - Printer.toString(90) | de.akquinet.spring.kundenverwaltung.db.Kunde{nachname=Meier, adresse=de.akquinet.spring.kundenverwaltung.db.Adresse#1081344, kundennummer=12345, vorname=Egon-Max, id=1048577}
DEBUG - AbstractBatcher.logOpenPreparedStatement(311) | about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
DEBUG - ConnectionManager.openConnection(415) | opening JDBC connection
DEBUG - Logger.debug(37) | StandardDataSource:getConnection Connection from DriverManager is returned
DEBUG - AbstractBatcher.log(346) | insert into PERSONEN (nachname, vorname, adresse, ID) values (?, ?, ?, ?)
DEBUG - AbstractBatcher.logClosePreparedStatement(319) | about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
DEBUG - JDBCExceptionReporter.logExceptions(63) | could not insert: [de.akquinet.spring.kundenverwaltung.db.Kunde] [insert into PERSONEN (nachname, vorname, adresse, ID) values (?, ?, ?, ?)]
ERROR 23503: INSERT on table 'PERSONEN' caused a violation of foreign key constraint 'FK491016BE65BE6C18' for key (1081344).  The statement has been rolled back.
   at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
   at org.apache.derby.impl.sql.execute.ForeignKeyRIChecker.doCheck(Unknown Source)
   at org.apache.derby.impl.sql.execute.GenericRIChecker.doCheck(Unknown Source)
   at org.apache.derby.impl.sql.execute.RISetChecker.doFKCheck(Unknown Source)
   at org.apache.derby.impl.sql.execute.InsertResultSet.normalInsertCore(Unknown Source)
   at org.apache.derby.impl.sql.execute.InsertResultSet.open(Unknown Source)
   at org.apache.derby.impl.sql.GenericPreparedStatement.execute(Unknown Source)
   at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(Unknown Source)
   at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(Unknown Source)
   at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeUpdate(Unknown Source)
   at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:23)
   at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2062)
   at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2427)
   at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:51)
   at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
   at org.springframework.orm.hibernate3.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:130)
   at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:48)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:707)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:523)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:510)
   at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:310)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:117)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:209)
   at $Proxy1.createKunde(Unknown Source)
   at de.akquinet.spring.kundenverwaltung.gui.KundenAnlegenDialog.legeKundeAn(KundenAnlegenDialog.java:139)
   at de.akquinet.spring.kundenverwaltung.gui.KundenAnlegenDialog.access$1(KundenAnlegenDialog.java:137)
   at de.akquinet.spring.kundenverwaltung.gui.KundenAnlegenDialog$2.actionPerformed(KundenAnlegenDialog.java:130)
   at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1849)
   at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2169)
   at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)
   at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)
   at javax.swing.AbstractButton.doClick(AbstractButton.java:302)
   at javax.swing.plaf.basic.BasicRootPaneUI$Actions.actionPerformed(BasicRootPaneUI.java:190)
   at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1571)
   at javax.swing.JComponent.processKeyBinding(JComponent.java:2763)
   at javax.swing.KeyboardManager.fireBinding(KeyboardManager.java:255)
   at javax.swing.KeyboardManager.fireKeyboardAction(KeyboardManager.java:204)
   at javax.swing.JComponent.processKeyBindingsForAllComponents(JComponent.java:2840)
   at javax.swing.JComponent.processKeyBindings(JComponent.java:2832)
   at javax.swing.JComponent.processKeyEvent(JComponent.java:2726)
   at java.awt.Component.processEvent(Component.java:5265)
   at java.awt.Container.processEvent(Container.java:1966)
   at java.awt.Component.dispatchEventImpl(Component.java:3955)
   at java.awt.Container.dispatchEventImpl(Container.java:2024)
   at java.awt.Component.dispatchEvent(Component.java:3803)
   at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1810)
   at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:672)
   at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:920)
   at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:798)
   at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:636)
   at java.awt.Component.dispatchEventImpl(Component.java:3841)
   at java.awt.Container.dispatchEventImpl(Container.java:2024)
   at java.awt.Window.dispatchEventImpl(Window.java:1778)
   at java.awt.Component.dispatchEvent(Component.java:3803)
   at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
   at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
   at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
   at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:153)
   at java.awt.Dialog$1.run(Dialog.java:517)
   at java.awt.Dialog$2.run(Dialog.java:545)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.awt.Dialog.show(Dialog.java:543)
   at java.awt.Component.show(Component.java:1300)
   at java.awt.Component.setVisible(Component.java:1253)
   at de.akquinet.spring.kundenverwaltung.gui.KundenlistePanel.legeNeuenKundenAn(KundenlistePanel.java:99)
   at de.akquinet.spring.kundenverwaltung.gui.KundenlistePanel.access$0(KundenlistePanel.java:98)
   at de.akquinet.spring.kundenverwaltung.gui.KundenlistePanel$1.actionPerformed(KundenlistePanel.java:91)
   at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1849)
   at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2169)
   at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)
   at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)
   at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
   at java.awt.Component.processMouseEvent(Component.java:5488)
   at javax.swing.JComponent.processMouseEvent(JComponent.java:3126)
   at java.awt.Component.processEvent(Component.java:5253)
   at java.awt.Container.processEvent(Container.java:1966)
   at java.awt.Component.dispatchEventImpl(Component.java:3955)
   at java.awt.Container.dispatchEventImpl(Container.java:2024)
   at java.awt.Component.dispatchEvent(Component.java:3803)
   at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4212)
   at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3892)
   at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3822)
   at java.awt.Container.dispatchEventImpl(Container.java:2010)
   at java.awt.Window.dispatchEventImpl(Window.java:1778)
   at java.awt.Component.dispatchEvent(Component.java:3803)
   at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
   at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
   at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
   at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
   at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
   at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
WARN - JDBCExceptionReporter.logExceptions(71) | SQL Error: 30000, SQLState: 23503

Name and version of the database you are using:
Derby, 10.1.3.1

The generated SQL (show_sql=true):
Hibernate: insert into PERSONEN (nachname, vorname, adresse, ID) values (?, ?, ?, ?)

Debug level Hibernate log excerpt:
s.a.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

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.