Hi,
I ran into some problems today when trying to use Hibernate and an ordered set. Since I could not figure out the problem myself I constructed a minimal example illustrating my problem.
I have a class called
Bar that only contains a java.util.SortedSet of
Foos called
fooSet. The
Foo, in turn, consists solely of a java.lang.Integer member and implements java.util.Comparable.
I would like to have a function that adds
Foos to the
fooSet of a
Bar. The problem is that when I call that function the second time an error occurs: "ERROR: duplicate key violates unique constraint "foo_pkey""
I guess the problem is that Hibernate tries to add the first foo to the table, even though it is already there. I am sure I have made an error somewhere, but I can't figure it out. Any help is appreciated.
More details below, and the complete example at
http://www.brasse.org/sorted-set-example.tar
regards
Mattias
Hibernate version:
2.1.8
Mapping documents:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="Bar" table="bar">
<id name="id" column="id" type="long" unsaved-value="null" access="field">
<generator class="native"/>
</id>
<set name="fooSet" table="foo" sort="natural">
<key column="id"/>
<composite-element class="Foo">
<property name="fooValue" column="foo_value" type="java.lang.Integer"
not-null="true" access="field"/>
</composite-element>
</set>
</class>
</hibernate-mapping>
Code:Code:
addToFooSet(barId, 2); // Fine
addToFooSet(barId, 3); // Error
private static void addToFooSet(Long barId, int fooValue)
throws HibernateException
{
Session s = sessionFactory.openSession();
Transaction tx = s.beginTransaction();
Bar bar = new Bar();
s.load(bar, new Long(barId));
bar.getFooSet().add(new Foo(new Integer(fooValue)));
s.saveOrUpdate(bar);
tx.commit();
s.close();
}
Full stack trace of any exception that occurs:Code:
16:20:40,952 DEBUG JDBCExceptionReporter:49 - could not insert collection rows: [Bar.fooSet#1]
java.sql.SQLException: ERROR: duplicate key violates unique constraint "foo_pkey"
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1471)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1256)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:175)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:388)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:329)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:281)
at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
at net.sf.hibernate.collection.AbstractCollectionPersister.insertRows(AbstractCollectionPersister.java:610)
at net.sf.hibernate.impl.ScheduledCollectionUpdate.execute(ScheduledCollectionUpdate.java:49)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2449)
at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2435)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2395)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2261)
at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
at Bar.addToFooSet(Bar.java:49)
at Bar.main(Bar.java:62)
16:20:40,955 WARN JDBCExceptionReporter:57 - SQL Error: 0, SQLState: 23505
16:20:40,956 ERROR JDBCExceptionReporter:58 - ERROR: duplicate key violates unique constraint "foo_pkey"
16:20:40,959 ERROR SessionImpl:2400 - Could not synchronize database state with session
Exception in thread "main" net.sf.hibernate.exception.ConstraintViolationException: could not insert collection rows: [Bar.fooSet#1]
at net.sf.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:62)
at net.sf.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:29)
at net.sf.hibernate.collection.AbstractCollectionPersister.convert(AbstractCollectionPersister.java:728)
at net.sf.hibernate.collection.AbstractCollectionPersister.insertRows(AbstractCollectionPersister.java:624)
at net.sf.hibernate.impl.ScheduledCollectionUpdate.execute(ScheduledCollectionUpdate.java:49)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2449)
at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2435)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2395)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2261)
at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
at Bar.addToFooSet(Bar.java:49)
at Bar.main(Bar.java:62)
Caused by: java.sql.SQLException: ERROR: duplicate key violates unique constraint "foo_pkey"
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1471)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1256)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:175)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:388)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:329)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:281)
at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
at net.sf.hibernate.collection.AbstractCollectionPersister.insertRows(AbstractCollectionPersister.java:610)
... 8 more
Name and version of the database you are using:
postgresql 7.4.6
The generated SQL (show_sql=true):
insert into foo (id, foo_value) values (?, ?)
Debug level Hibernate log excerpt:
see
http://www.brasse.org/sorted-set-example.tar