I am using Hibernete 2.1, with HSQLDB 1.7.1.
This is a further simplification of a previous post which is still causing me problems. Essentially a call to collections.contains(x) is returning false where it should be returning true.
I checked my code carefully and both hashCode() and equals() are correct.
Here is the code:
Code:
// ensure that 'group' is updated
ChannelGroup group is set to a valid ChannelGroup...
session = sessions.openSession()
transaction = session.beginTransaction();
session.update(group);
// get first channel in collection
Collection channels = group.getChannelGroup().getChannels();
Iterator iter = channels.iterator();
channel = (Channel) iter.next();
// Close transaction
transaction.commit();
session.flush();
session.close();
session = null;
transaction = null;
// Start a new one (needed?)
session = sessions.openSession()
transaction = session.beginTransaction();
// *** PROBLEM OCCURS HERE
assert (group.channels.contains(channel)) // fails!
transaction.commit();
session.flush();
session.close();
Note that that channels is a Set.
If I single step through this, I note the following:
- I can verify that the hashCode for channel equals the hashCode for the first non-null element of channels.
- the channels.contains() call is actually implemented by net.sf.hibernate.collection.Set
- Which in turn calls java.util.HashSet.contains()
- Which in turn calls java.util.HashMap.contains()
- Which FAILS to find the identical entry.
(By the way while I am positive about the fact that HashSet and HashMap methods are being called, due to the absence of debug info I am not 100% sure those are the specific methods.)
Can you tell what's wrong?
Thanks!
Here is the mapping for ChannelGroup
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="de.nava.informa.impl.hibernate.ChannelGroup"
table="CHANNEL_GROUPS"
dynamic-update="false"
dynamic-insert="false"
>
<id
name="intId"
column="CHANNEL_GROUP_ID"
type="integer"
>
<generator class="native">
</generator>
</id>
<property
name="title"
type="java.lang.String"
update="true"
insert="true"
column="TITLE"
not-null="true"
/>
<set
name="channels"
table="CAT_GROUP_CHANNEL"
lazy="true"
inverse="false"
cascade="none"
sort="unsorted"
>
<key
column="GROUP_ID"
/>
<many-to-many
class="de.nava.informa.impl.hibernate.Channel"
column="CHANNEL_ID"
outer-join="auto"
/>
</set>
<many-to-one
name="parent"
class="de.nava.informa.impl.hibernate.ChannelGroup"
cascade="none"
outer-join="auto"
update="true"
insert="true"
column="PARENT_ID"
/>
<bag
name="children"
lazy="true"
inverse="false"
cascade="none"
order-by="CHANNEL_GROUP_ID"
>
<key
column="PARENT_ID"
/>
<one-to-many
class="de.nava.informa.impl.hibernate.ChannelGroup"
/>
</bag>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-ChannelGroup.xml
containing the additional properties and place it in your merge dir.
-->
</class>
</hibernate-mapping>
And here is the mapping for 'Channel':
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="de.nava.informa.impl.hibernate.Channel"
table="CHANNELS"
dynamic-update="false"
dynamic-insert="false"
>
<id
name="intId"
column="CHANNEL_ID"
type="integer"
>
<generator class="native">
</generator>
</id>
<property
name="title"
type="java.lang.String"
update="true"
insert="true"
column="TITLE"
not-null="true"
/>
<property
name="description"
type="java.lang.String"
update="true"
insert="true"
column="DESCRIPTION"
/>
<property
name="locationString"
type="string"
update="true"
insert="true"
column="LOCSTRING"
/>
<property
name="site"
type="java.net.URL"
update="true"
insert="true"
column="SITE"
/>
<property
name="creator"
type="java.lang.String"
update="true"
insert="true"
column="CREATOR"
/>
<property
name="publisher"
type="java.lang.String"
update="true"
insert="true"
column="PUBLISHER"
/>
<property
name="language"
type="java.lang.String"
update="true"
insert="true"
column="LANGUAGE"
/>
<property
name="formatString"
type="string"
update="true"
insert="true"
column="FORMAT"
/>
<bag
name="items"
table="ITEMS"
lazy="false"
inverse="false"
cascade="all"
>
<key
column="CHANNEL_ID"
/>
<one-to-many
class="de.nava.informa.impl.hibernate.Item"
/>
</bag>
<many-to-one
name="image"
class="de.nava.informa.impl.hibernate.Image"
cascade="none"
outer-join="auto"
update="true"
insert="true"
column="IMAGE_ID"
not-null="false"
/>
<many-to-one
name="textInput"
class="de.nava.informa.impl.hibernate.TextInput"
cascade="none"
outer-join="auto"
update="true"
insert="true"
column="TEXTINPUT_ID"
not-null="false"
/>
<property
name="copyright"
type="java.lang.String"
update="true"
insert="true"
column="COPYRIGHT"
/>
<property
name="rating"
type="java.lang.String"
update="true"
insert="true"
column="RATING"
/>
<many-to-one
name="cloud"
class="de.nava.informa.impl.hibernate.Cloud"
cascade="none"
outer-join="auto"
update="true"
insert="true"
column="CLOUD_ID"
not-null="false"
/>
<property
name="generator"
type="java.lang.String"
update="true"
insert="true"
column="GENERATOR"
/>
<property
name="docs"
type="java.lang.String"
update="true"
insert="true"
column="DOCS"
/>
<property
name="ttl"
type="int"
update="true"
insert="true"
column="TTL"
/>
<bag
name="categories"
table="CAT_CHANNEL_LINK"
lazy="true"
inverse="false"
cascade="none"
>
<key
column="CHANNEL_ID"
/>
<many-to-many
class="de.nava.informa.impl.hibernate.Category"
column="CATEGORY_ID"
outer-join="auto"
/>
</bag>
<property
name="lastUpdated"
type="java.util.Date"
update="true"
insert="true"
column="LAST_UPDATED"
/>
<property
name="lastBuildDate"
type="java.util.Date"
update="true"
insert="true"
column="LAST_BUILD_DATE"
/>
<property
name="pubDate"
type="java.util.Date"
update="true"
insert="true"
column="PUB_DATE"
/>
<property
name="updatePeriod"
type="java.lang.String"
update="true"
insert="true"
column="UPDATE_PERIOD"
/>
<property
name="updateFrequency"
type="int"
update="true"
insert="true"
column="UPDATE_FREQUENCY"
/>
<property
name="updateBase"
type="java.util.Date"
update="true"
insert="true"
column="UPDATE_BASE"
/>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-Channel.xml
containing the additional properties and place it in your merge dir.
-->
</class>
</hibernate-mapping>