-->
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: bi many-to-many problems...
PostPosted: Tue Dec 16, 2003 5:42 pm 
Regular
Regular

Joined: Wed Aug 27, 2003 2:55 am
Posts: 90
Location: Sweden
Hi,

Been struggling with this prob a couple of hours by now, can't solve it. Suppose my head is not where it should be right now, maybe someone could help me out?

I got this object semantics: City many-to-many ZipCode (bi-directional)

I'd like to:

1. Be able to remove a ZipCode, it rows in the association table but NOT any Cities

2. Be able to remove a City, it rows in the association table but NOT any ZipCodes

The object graph I'm working on consists of two cities associated with the same zipcode. Deleting one city succeeds, but deleting the zipcode doesn't :-/

Here's my 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="eriksson.andreas.data.CityImpl" table="cities">
   
        <id name="cityId" column="cityId">
            <generator class="uuid.hex"/>
        </id>
       
        <property name="cityName" column="cityName"/>
       
        <set name="zipCodes" table="cityzipcodes">
            <key column="cityId"/>
            <many-to-many column="zipCodeId" class="eriksson.andreas.data.ZipCodeImpl"/>
        </set>
    </class>
</hibernate-mapping>

<?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="eriksson.andreas.data.ZipCodeImpl" table="zipcodes">
   
        <id name="zipCodeId" column="zipCodeId">
            <generator class="uuid.hex"/>
        </id>
       
        <property name="zipCode" column="zipCode"/>
       
        <set name="cities" table="cityzipcodes" inverse="true">
            <key column="zipCodeId"/>
            <many-to-many column="cityId" class="eriksson.andreas.data.CityImpl"/>
        </set>
    </class>
</hibernate-mapping>


Here's my Service:

Code:
/* (non-Javadoc)
     * @see eriksson.andreas.services.AreaService#deleteCity(eriksson.andreas.data.City)
     */
    public void deleteCity(final City cityToDelete) {
        TransactionTemplate transactionTemplate = new TransactionTemplate(
            this.getPlatformTransactionManager());
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            public void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                getCityDao().delete(cityToDelete);
            }
        });
    }

    /* (non-Javadoc)
     * @see eriksson.andreas.services.AreaService#deleteZipCode(eriksson.andreas.data.ZipCode)
     */
    public void deleteZipCode(final ZipCode zipCodeToDelete) {
        TransactionTemplate transactionTemplate = new TransactionTemplate(
            this.getPlatformTransactionManager());
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            public void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                getZipCodeDao().delete(zipCodeToDelete);
            }
        });
    }


Here's the SQL for generating the tables:
Code:
create table cities (
   cityId varchar(32) not null,
   cityName varchar(100) not null unique,
   primary key(cityId))

create table zipcodes (
   zipCodeId varchar(32),
   zipCode int(5) not null check (zipCode >= 10000) unique,
   primary key(zipCodeId))

create table cityzipcodes (
   cityId varchar(32) not null,
   zipCodeId varchar(32) not null,
   primary key (cityId, zipCodeId),
   foreign key (cityId) references cities(cityId),
   foreign key (zipCodeId) references zipcodes(zipCodeId))


Here's the log:

Code:
22:40:51,526 DEBUG HibernateTransactionManager:94 - Using transaction object [org.springframework.orm.hibernate.HibernateTransactionObject@4865ce]
22:40:51,526 DEBUG HibernateTransactionManager:217 - Opening new session for Hibernate transaction
22:40:51,526 DEBUG SessionFactoryUtils:91 - Opening Hibernate session
22:40:51,536 DEBUG SessionImpl:526 - opened session
22:40:51,536 DEBUG HibernateTransactionManager:223 - Beginning Hibernate transaction
22:40:51,536 DEBUG JDBCTransaction:37 - begin
22:40:51,536 DEBUG JDBCTransaction:41 - current autocommit status:true
22:40:51,546 DEBUG JDBCTransaction:43 - disabling autocommit
22:40:51,556 DEBUG TransactionSynchronizationManager:107 - Bound value [org.springframework.orm.hibernate.SessionHolder@113beb5] for key [net.sf.hibernate.impl.SessionFactoryImpl@1cffeb4] to thread [main]
22:40:51,556 DEBUG TransactionSynchronizationManager:90 - Retrieved value [org.springframework.orm.hibernate.SessionHolder@113beb5] for key [net.sf.hibernate.impl.SessionFactoryImpl@1cffeb4] bound to thread [main]
22:40:51,556 DEBUG SessionImpl:1070 - deleting a transient instance
22:40:51,556 DEBUG SessionImpl:1117 - deleting [eriksson.andreas.data.ZipCodeImpl#4028800ef980fbe700f980fbef900002]
22:40:51,566 DEBUG HibernateTransactionManager:145 - Triggering beforeCommit synchronization
22:40:51,566 DEBUG HibernateTransactionManager:147 - Triggering beforeCompletion synchronization
22:40:51,566 DEBUG HibernateTransactionManager:149 - Initiating transaction commit
22:40:51,566 DEBUG HibernateTransactionManager:285 - Committing Hibernate transaction
22:40:51,566 DEBUG JDBCTransaction:59 - commit
22:40:51,566 DEBUG SessionImpl:2188 - flushing session
22:40:51,566 DEBUG SessionImpl:337 - Collection dirty: [eriksson.andreas.data.ZipCodeImpl.cities#4028800ef980fbe700f980fbef900002]
22:40:51,576 DEBUG SessionImpl:2316 - Flushing entities and processing referenced collections
22:40:51,576 DEBUG SessionImpl:2659 - Processing unreferenced collections
22:40:51,576 DEBUG SessionImpl:2780 - Collection dereferenced: [eriksson.andreas.data.ZipCodeImpl.cities#4028800ef980fbe700f980fbef900002]
22:40:51,576 DEBUG SessionImpl:2673 - Scheduling collection removes/(re)creates/updates
22:40:51,586 DEBUG SessionImpl:3234 - running Session.finalize()
22:40:51,586 DEBUG SessionImpl:2212 - Flushed: 0 insertions, 0 updates, 1 deletions to 1 objects
22:40:51,586 DEBUG SessionImpl:2217 - Flushed: 0 (re)creations, 0 updates, 1 removals to 1 collections
22:40:51,586 DEBUG Printer:75 - listing entities:
22:40:51,596 DEBUG Printer:82 - eriksson.andreas.data.ZipCodeImpl{cities=[CityImpl#4028800ef980fbe700f980fbf0260003, CityImpl#4028800ef980fbe700f980fbee6d0001], zipCodeId=4028800ef980fbe700f980fbef900002, zipCode=75755}
22:40:51,596 DEBUG SessionImpl:2253 - executing flush
22:40:51,596 DEBUG EntityPersister:597 - Deleting entity: [eriksson.andreas.data.ZipCodeImpl#4028800ef980fbe700f980fbef900002]
22:40:51,596 DEBUG BatcherImpl:192 - about to open: 0 open PreparedStatements, 0 open ResultSets
22:40:51,596 DEBUG BatcherImpl:226 - prepared statement get: delete from zipcodes where zipCodeId=?
Hibernate: delete from zipcodes where zipCodeId=?
22:40:51,606 DEBUG BatcherImpl:232 - preparing statement
22:40:51,606 DEBUG StringType:46 - binding '4028800ef980fbe700f980fbef900002' to parameter: 1
22:40:51,616 DEBUG BatcherImpl:199 - done closing: 0 open PreparedStatements, 0 open ResultSets
22:40:51,616 DEBUG BatcherImpl:245 - closing statement
22:40:51,636 DEBUG JDBCExceptionReporter:36 - SQL Exception
java.sql.SQLException: UPDATE or DELETE operation invalid because the referenced table  does not satisfy a referential constraint
   at com.mimer.jdbc.Connection.a(Unknown Source)
   at com.mimer.jdbc.aa.do(Unknown Source)
   at com.mimer.jdbc.Statement.a(Unknown Source)
   at com.mimer.jdbc.PreparedStatement.execute(Unknown Source)
   at com.mimer.jdbc.PreparedStatement.executeUpdate(Unknown Source)
   at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:233)
   at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
   at net.sf.hibernate.persister.EntityPersister.delete(EntityPersister.java:626)
   at net.sf.hibernate.impl.ScheduledDeletion.execute(ScheduledDeletion.java:29)
   at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2303)
   at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2261)
   at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2182)
   at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
   at org.springframework.orm.hibernate.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:287)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:150)
   at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:109)
   at eriksson.andreas.services.AreaServiceImpl.deleteZipCode(AreaServiceImpl.java:208)
   at eriksson.andreas.client.TestClient.main(TestClient.java:56)
22:40:51,636  WARN JDBCExceptionReporter:38 - SQL Error: -10106, SQLState: 23000
22:40:51,636 ERROR JDBCExceptionReporter:46 - UPDATE or DELETE operation invalid because the referenced table  does not satisfy a referential constraint
22:40:51,656 ERROR JDBCExceptionReporter:38 - could not delete: [eriksson.andreas.data.ZipCodeImpl#4028800ef980fbe700f980fbef900002]
java.sql.SQLException: UPDATE or DELETE operation invalid because the referenced table  does not satisfy a referential constraint
   at com.mimer.jdbc.Connection.a(Unknown Source)
   at com.mimer.jdbc.aa.do(Unknown Source)
   at com.mimer.jdbc.Statement.a(Unknown Source)
   at com.mimer.jdbc.PreparedStatement.execute(Unknown Source)
   at com.mimer.jdbc.PreparedStatement.executeUpdate(Unknown Source)
   at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:233)
   at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
   at net.sf.hibernate.persister.EntityPersister.delete(EntityPersister.java:626)
   at net.sf.hibernate.impl.ScheduledDeletion.execute(ScheduledDeletion.java:29)
   at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2303)
   at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2261)
   at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2182)
   at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
   at org.springframework.orm.hibernate.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:287)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:150)
   at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:109)
   at eriksson.andreas.services.AreaServiceImpl.deleteZipCode(AreaServiceImpl.java:208)
   at eriksson.andreas.client.TestClient.main(TestClient.java:56)
22:40:51,656 ERROR SessionImpl:2264 - Could not synchronize database state with session
net.sf.hibernate.JDBCException: could not delete: [eriksson.andreas.data.ZipCodeImpl#4028800ef980fbe700f980fbef900002]
   at net.sf.hibernate.persister.EntityPersister.delete(EntityPersister.java:645)
   at net.sf.hibernate.impl.ScheduledDeletion.execute(ScheduledDeletion.java:29)
   at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2303)
   at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2261)
   at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2182)
   at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
   at org.springframework.orm.hibernate.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:287)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:150)
   at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:109)
   at eriksson.andreas.services.AreaServiceImpl.deleteZipCode(AreaServiceImpl.java:208)
   at eriksson.andreas.client.TestClient.main(TestClient.java:56)
Caused by: java.sql.SQLException: UPDATE or DELETE operation invalid because the referenced table  does not satisfy a referential constraint
   at com.mimer.jdbc.Connection.a(Unknown Source)
   at com.mimer.jdbc.aa.do(Unknown Source)
   at com.mimer.jdbc.Statement.a(Unknown Source)
   at com.mimer.jdbc.PreparedStatement.execute(Unknown Source)
   at com.mimer.jdbc.PreparedStatement.executeUpdate(Unknown Source)
   at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:233)
   at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
   at net.sf.hibernate.persister.EntityPersister.delete(EntityPersister.java:626)
   ... 10 more
22:40:51,666  WARN SQLStateSQLExceptionTranslator:51 - Translating SQLException with SQLState '23000' and errorCode '-10106' and message [UPDATE or DELETE operation invalid because the referenced table  does not satisfy a referential constraint]; SQL was [null] for task [HibernateTemplate]
22:40:51,666 DEBUG HibernateTransactionManager:305 - Rolling back Hibernate transaction
22:40:51,666 DEBUG JDBCTransaction:82 - rollback
22:40:51,676 DEBUG SessionImpl:556 - transaction completion
22:40:51,676 DEBUG JDBCTransaction:103 - re-enabling autocommit
22:40:51,676 DEBUG HibernateTransactionManager:241 - Triggering afterCompletion synchronization
22:40:51,676 DEBUG TransactionSynchronizationManager:122 - Removed value [org.springframework.orm.hibernate.SessionHolder@113beb5] for key [net.sf.hibernate.impl.SessionFactoryImpl@1cffeb4] from thread [main]
22:40:51,686 DEBUG HibernateTransactionManager:361 - Closing Hibernate session after transaction
22:40:51,686 DEBUG SessionFactoryUtils:179 - Closing Hibernate session
22:40:51,686 DEBUG SessionImpl:544 - closing session
22:40:51,686 DEBUG SessionImpl:3182 - disconnecting session
22:40:51,686 DEBUG SessionImpl:556 - transaction completion
org.springframework.dao.DataIntegrityViolationException: (HibernateTemplate): data integrity violated by SQL 'null'; nested exception is:
   java.sql.SQLException: UPDATE or DELETE operation invalid because the referenced table  does not satisfy a referential constraint
java.sql.SQLException: UPDATE or DELETE operation invalid because the referenced table  does not satisfy a referential constraint
   at com.mimer.jdbc.Connection.a(Unknown Source)
   at com.mimer.jdbc.aa.do(Unknown Source)
   at com.mimer.jdbc.Statement.a(Unknown Source)
   at com.mimer.jdbc.PreparedStatement.execute(Unknown Source)
   at com.mimer.jdbc.PreparedStatement.executeUpdate(Unknown Source)
   at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:233)
   at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
   at net.sf.hibernate.persister.EntityPersister.delete(EntityPersister.java:626)
   at net.sf.hibernate.impl.ScheduledDeletion.execute(ScheduledDeletion.java:29)
   at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2303)
   at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2261)
   at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2182)
   at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
   at org.springframework.orm.hibernate.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:287)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:150)
   at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:109)
   at eriksson.andreas.services.AreaServiceImpl.deleteZipCode(AreaServiceImpl.java:208)
   at eriksson.andreas.client.TestClient.main(TestClient.java:56)
Exception in thread "main"


Kind regards, Andreas


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 17, 2003 4:41 am 
Regular
Regular

Joined: Wed Aug 27, 2003 2:55 am
Posts: 90
Location: Sweden
Pushing it up...


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 17, 2003 7:56 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Remove thze inverse="true" but I think you'll have some other issues.
The other solution is to add a method deleteLink whick look at the city and remove the link from the right side.

You're a "pushing it up" ace, are you ?

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 17, 2003 9:18 am 
Regular
Regular

Joined: Wed Aug 27, 2003 2:55 am
Posts: 90
Location: Sweden
If I remove the inverse="true" I'll get the City object trying to insert into the association table AND the ZipCode trying to insert into the association table.

Removing the link from right side? Don't really get what you mean...

If I delete a City I have helper methods in the value object City which removes itself from any collection it exists in. The same goes for ZipCode. Maybe that's what you mean?

Quote:
You're a "pushing it up" ace, are you ?


Well, yeah if I'm not going to drown in the flood ;-)

Kind regards, Andreas


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 17, 2003 10:04 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
andreas_eriksson wrote:
If I remove the inverse="true" I'll get the City object trying to insert into the association table AND the ZipCode trying to insert into the association table.

Hum expected indeed.

Quote:
Removing the link from right side? Don't really get what you mean...

If I delete a City I have helper methods in the value object City which removes itself from any collection it exists in. The same goes for ZipCode. Maybe that's what you mean?

Almost.
From the ZipCode side, get all cities linked with this zip code and remove the link from the city point of view.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 17, 2003 11:01 am 
Regular
Regular

Joined: Wed Aug 27, 2003 2:55 am
Posts: 90
Location: Sweden
Quote:
From the ZipCode side, get all cities linked with this zip code and remove the link from the city point of view.


Ok, I've got it. Will try it out later tonight!

I'll keep you posted, thanks!

Kind regards, Andreas


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 17, 2003 3:41 pm 
Regular
Regular

Joined: Wed Aug 27, 2003 2:55 am
Posts: 90
Location: Sweden
I'v solved the problem thanks to epbernard :-)

In my mapping files, I removed the inverse="true". And I'm not using any cascade.

In both City value object and ZipCode value object I implemented the following helper method:

City.java
Code:
public void delete() {
    Set zipCodes = this.getZipCodes();
    if (zipCodes != null) {
        Iterator zipCodeIterator = zipCodes.iterator();
        while (zipCodeIterator.hasNext()) {
            ZipCode zipCode = (ZipCode) zipCodeIterator.next();
            Set cities = zipCode.getCities();
            if (cities != null) {
                cities.remove(this);
            }
        }
    }
}


, and a corresponding in ZipCode.java.

Then just before calling the "session.delete()" I invoke the delete() method on the current value object.

Thanks a bunch!

Kind regards, Andreas


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.