-->
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.  [ 7 posts ] 
Author Message
 Post subject: Batch update row count wrong & transient instance proble
PostPosted: Wed Jan 19, 2005 4:55 pm 
Beginner
Beginner

Joined: Thu Jan 06, 2005 6:11 am
Posts: 32
Location: Magdeburg, Germany
This mapping gives me two problems and endless hours of headache.. :-/

I'm using spring hibernate and transaction interceptors.


First error:

If I try to delete an already deleted instance of Account, I don't get the Exception on session.delete, but later if the transaction interceptor tries to flush the session.

If I insert a session.flush(); after session.delete, the HibernateException is thrown immediately. Why don't I get a "ObjectNotFoundException"? If using the same code on objects without collections, it works perfectly with catching the ObjectNotFoundException.

Seems like something with the collection mapping doesn't work.


Code:
   protected void deletePersistable(Persistable persistable) throws DataAccessException,
         PersistableNotFoundException {
      if (persistable.getId() == null)
         throw new PersistableNotFoundException("id was null");

      Session session = SessionFactoryUtils.getSession(getSessionFactory(),
            false);
      try {
         session.delete(persistable);
      } catch (ObjectNotFoundException ex) {
         throw new PersistableNotFoundException("persistable with id "
               + persistable.getId() + " unknown!");
      } catch (HibernateException ex) {
         SessionFactoryUtils.convertHibernateAccessException(ex);
      }
   }


Code:
19.01.2005 21:31:27 net.sf.hibernate.impl.SessionImpl execute
SCHWERWIEGEND: Could not synchronize database state with session
org.springframework.orm.hibernate.HibernateSystemException: Batch update row count wrong: 0; nested exception is net.sf.hibernate.HibernateException: Batch update row count wrong: 0
net.sf.hibernate.HibernateException: Batch update row count wrong: 0
   at net.sf.hibernate.impl.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:65)
   at net.sf.hibernate.impl.BatcherImpl.executeBatch(BatcherImpl.java:127)
   at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2441)
   at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2392)
   at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2260)
   at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
   at org.springframework.orm.hibernate.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:464)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:376)
   at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(TransactionAspectSupport.java:242)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:66)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:174)
   at $Proxy0.delete(Unknown Source)
   at portal.dao.hibernate.TestAccountDaoImpl.testDelete(TestAccountDaoImpl.java:138)
JUNIT TRACE REMOVED


Second error:

For integration testing purposes with dbunit, I create a new instance if Account, totally identical to my database representation. Then I load another Account instance with the same Id from the database, and perform an equality check. This works perfectly, and I also checked toString representations of both instances - they are identical, except for the string representation of the Set has the order of Addresses changed. They are equal anyway.

But If trying to delete the programatically created instance, I get an exception telling me that an Address is transient and unsaved... :-/

Code:

org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before flushing: net.suendhaft.portal.bo.Address
   at org.springframework.orm.hibernate.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:536)
   at org.springframework.orm.hibernate.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:564)
   at org.springframework.orm.hibernate.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:476)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:376)
   at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(TransactionAspectSupport.java:242)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:66)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:174)
   at $Proxy0.delete(Unknown Source)
   at net.suendhaft.portal.dao.hibernate.TestAccountDaoImpl.testDelete(TestAccountDaoImpl.java:132)


Hibernate version: 2.1.7c

Mapping documents:

Documents are shortened to relevant parts, original mapping files are rather huge...

Code:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping
>
    <class
        name="portal.bo.Account"
        table="account"
        dynamic-update="false"
        dynamic-insert="false"
        select-before-update="false"
        optimistic-lock="version"
    >

        <id
            name="id"
            type="java.lang.Integer"
        >
                <column
                    name="id"
                    sql-type="INT(11) UNSIGNED"
                />
            <generator class="identity">
            </generator>
        </id>


        <component
            name="person1"
            class="portal.bo.component.Person"
        >

        <many-to-one
            name="address"
            class="portal.bo.Address"
            cascade="all"
            outer-join="auto"
            update="true"
            insert="true"
            access="field"
        >
            <column
                name="p1_address"
                not-null="true"
            />
        </many-to-one>

        </component>

        <component
            name="person2"
            class="portal.bo.component.Person"
        >

        <many-to-one
            name="address"
            class="portal.bo.Address"
            cascade="all"
            outer-join="auto"
            update="true"
            insert="true"
            access="field"
        >
            <column
                name="p2_address"
                not-null="true"
            />
        </many-to-one>

        </component>

        <set
            name="addresses"
            lazy="false"
            inverse="true"
            cascade="all-delete-orphan"
            sort="unsorted"
        >

              <key
                  column="account"
              >
              </key>

              <one-to-many
                  class="portal.bo.Address"
              />

        </set>
    </class>

</hibernate-mapping>


Code:
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping
>
    <class
        name="portal.bo.Address"
        table="address"
        dynamic-update="false"
        dynamic-insert="false"
        select-before-update="false"
        optimistic-lock="version"
    >

        <id
            name="id"
            type="java.lang.Integer"
        >
                <column
                    name="id"
                    sql-type="INT(11) UNSIGNED"
                />
            <generator class="identity">
            </generator>
        </id>


        <many-to-one
            name="account"
            class="portal.bo.Account"
            cascade="none"
            outer-join="auto"
            update="true"
            insert="true"
            access="property"
        >
            <column
                name="account"
            />
        </many-to-one>

    </class>

</hibernate-mapping>



Name and version of the database you are using: MySQL 4.1


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 19, 2005 6:19 pm 
Beginner
Beginner

Joined: Thu Jan 06, 2005 6:11 am
Posts: 32
Location: Magdeburg, Germany
ok, first topic resolved:

transient instance problem occured since in my equality comparisons I didn't use the database identifier, as it is recommended to use only business key equality for good reason.

I simply forgot to set the id of my address objects. *bangingheadontable*gg*

The batch update problem still exists...


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 19, 2005 6:57 pm 
Beginner
Beginner

Joined: Thu Jan 06, 2005 6:11 am
Posts: 32
Location: Magdeburg, Germany
I looked into the query log of the server:

Last thing hibernate tries is updating the (of course nonexisting) account row in order to dereference the addresses in the person components.

I'll investigate further, but at the moment it looks to me like hibernate always wants to execute all batch rows without checking if the first query did succeed and throwing an Object not found exception instead (sorry, I don't have too much insight into hibernate core, so my assumption may be wrong...)

I'll switch on debug log and investigate further.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 19, 2005 7:45 pm 
Beginner
Beginner

Joined: Thu Jan 06, 2005 6:11 am
Posts: 32
Location: Magdeburg, Germany
debug log:


Code:
00:24:14,034 DEBUG SessionImpl:558 - opened session
00:24:14,034 DEBUG SessionImpl:1141 - deleting a transient instance
00:24:14,034 DEBUG SessionImpl:1296 - collection dereferenced while transient [portal.bo.Account.addresses#1]
00:24:14,044 DEBUG SessionImpl:1188 - deleting [portal.bo.Account#1]
00:24:14,044 DEBUG Cascades:497 - processing cascades for: portal.bo.Account
00:24:14,044 DEBUG Cascades:524 - cascading to collection: portal.bo.Account.addresses
00:24:14,044 DEBUG Cascades:60 - cascading to delete()
00:24:14,044 DEBUG Cascades:341 - id unsaved-value strategy NULL
00:24:14,044 DEBUG SessionImpl:1141 - deleting a transient instance
00:24:14,044 DEBUG SessionImpl:1188 - deleting [portal.bo.Address#2]
00:24:14,054 DEBUG Cascades:60 - cascading to delete()
00:24:14,054 DEBUG Cascades:341 - id unsaved-value strategy NULL
00:24:14,054 DEBUG SessionImpl:1141 - deleting a transient instance
00:24:14,054 DEBUG SessionImpl:1188 - deleting [portal.bo.Address#1]
00:24:14,054 DEBUG Cascades:60 - cascading to delete()
00:24:14,054 DEBUG Cascades:341 - id unsaved-value strategy NULL
00:24:14,064 DEBUG SessionImpl:1141 - deleting a transient instance
00:24:14,064 DEBUG SessionImpl:1188 - deleting [portal.bo.Address#3]
00:24:14,064 DEBUG Cascades:506 - done processing cascades for: portal.bo.Account
00:24:14,074 DEBUG Cascades:497 - processing cascades for: portal.bo.Account
00:24:14,074 DEBUG Cascades:506 - done processing cascades for: portal.bo.Account
00:24:14,074 DEBUG SessionImpl:2266 - flushing session
00:24:14,074 DEBUG SessionImpl:2459 - Flushing entities and processing referenced collections
00:24:14,074 DEBUG WrapVisitor:81 - Wrapped collection in role: portal.bo.Account.addresses
00:24:14,084 DEBUG AbstractEntityPersister:283 - portal.bo.Account.person1 is dirty
00:24:14,084 DEBUG AbstractEntityPersister:283 - portal.bo.Account.person2 is dirty
00:24:14,084 DEBUG SessionImpl:2550 - Updating deleted entity: [portal.bo.Account#1]
00:24:14,084 DEBUG SessionImpl:2800 - Processing unreferenced collections
00:24:14,084 DEBUG SessionImpl:2814 - Scheduling collection removes/(re)creates/updates
00:24:14,084 DEBUG SessionImpl:2290 - Flushed: 0 insertions, 1 updates, 4 deletions to 4 objects
00:24:14,084 DEBUG SessionImpl:2295 - Flushed: 0 (re)creations, 0 updates, 1 removals to 1 collections
00:24:14,094 DEBUG Printer:75 - listing entities:
00:24:14,094 DEBUG Printer:82 - portal.bo.Address{account=Account#1, id=1}
00:24:14,094 DEBUG Printer:82 - portal.bo.Account{addresses=[Address#2, Address#1, Address#3], person1=Person{address=Address#1}, person2=Person{address=Address#2}, id=1}
00:24:14,094 DEBUG Printer:82 - portal.bo.Address{account=Account#1, id=2}
00:24:14,104 DEBUG Printer:82 - portal.bo.Address{account=Account#1, id=3}
00:24:14,104 DEBUG SessionImpl:2379 - executing flush
00:24:14,104 DEBUG EntityPersister:629 - Updating entity: [portal.bo.Account#1]
00:24:14,104 DEBUG BatcherImpl:203 - about to open: 0 open PreparedStatements, 0 open ResultSets
00:24:14,125 DEBUG SQL:229 - update account set ... (SHORTENED, SQL STATEMENT FOR DEREFERENCING ADDRESSES, OF COURSE THIS FAILS)
00:24:14,125 DEBUG BatcherImpl:252 - preparing statement
00:24:14,125 DEBUG EntityPersister:384 - Dehydrating entity: [portal.bo.Account#1]
00:24:14,185 DEBUG BatcherImpl:28 - Adding to batch
00:24:14,185 DEBUG BatcherImpl:50 - Executing batch size: 1
00:24:14,185 DEBUG BatcherImpl:210 - done closing: 0 open PreparedStatements, 0 open ResultSets
00:24:14,185 DEBUG BatcherImpl:272 - closing statement
00:24:14,195 ERROR SessionImpl:2399 - Could not synchronize database state with session
00:24:14,195 DEBUG SessionImpl:576 - closing session
00:24:14,195 DEBUG SessionImpl:3371 - disconnecting session
00:24:14,195 DEBUG SessionImpl:594 - transaction completion


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 19, 2005 8:04 pm 
Beginner
Beginner

Joined: Thu Jan 06, 2005 6:11 am
Posts: 32
Location: Magdeburg, Germany
Any suggestions? Is this behaviour on purpose if trying to delete a nonexistent instance?

Is it possible to change the code somehow so I get an ObjectNotFoundException?

I'm really not that much of a hibernate professional so I could change the core files...

Best regards
Gregor


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 20, 2005 4:01 am 
Beginner
Beginner

Joined: Thu Jan 06, 2005 6:11 am
Posts: 32
Location: Magdeburg, Germany
http://opensource.atlassian.com/projects/hibernate/browse/HHH-85
http://forum.hibernate.org/viewtopic.php?t=935136

Actually this looks like an open bug (or at least unexpected behaviour) to me, which Gavin Kig fixed in Hibernate3.

Will there be an update for 2.1, too?

I'm not able to do it myself...


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 20, 2005 4:36 am 
Beginner
Beginner

Joined: Thu Jan 06, 2005 6:11 am
Posts: 32
Location: Magdeburg, Germany
Submitted to JIRA:

http://opensource.atlassian.com/projects/hibernate/browse/HB-1393


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

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.