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