-->
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.  [ 5 posts ] 
Author Message
 Post subject: Collection Set with Sort -> children with same name dropp
PostPosted: Mon Jul 19, 2004 11:01 pm 
Newbie

Joined: Tue Jan 06, 2004 8:06 am
Posts: 13
Hi

I've come across this problem and I can't quite grasp the logic behind it. Appreciate it if anyone can help elaborate the why.

We have a simple parent-child relationship (self-referential table) with additional implementation of name sorting routine.
ID = PK
PARENT_ID = FK

And I have in the db:

ID | Name | PK
--------------------
CatA | CatA |
CatB | CatX | CatA
CatC | CatX | CatA


Understand that Set is "A collection that contains no duplicate elements". In theory, CatA will have 2 childrens (CatB, CatC). This is reflected correctly if I declare set in hbm.xml as
<set name="children" inverse="false">

However, after I implemented the comparator, CatA returns only 1 children (CatB).
<set name="children" inverse="false" sort="com.test.CatNameComparator">

I am guessing since Set does not allow duplicate elements, CatC is not being added as child because it share the same name as CatB. But the part I cant comprehense is why is it so when my PK is ID and not Name.



Below is the HBM and CatNameComparator.java.

----------------------------------------------------------------------------
<hibernate-mapping>
<class name="com.test.Cat" table="CAT">
<id name="id" column="ID" type="string" length="32">
<generator class="uuid.hex"/>
</id>

<property name="name" column="name" type="string" length="40"/>

<many-to-one name="parent" column="PARENT_ID" class="com.test.Cat" />

<set name="children" inverse="false" sort="com.test.CatNameComparator">
<key column="PARENT_ID"/>
<one-to-many class="com.test.Cat"/>
</set>

</class>
</hibernate-mapping>
----------------------------------------------------------------------------

public class CatNameComparator implements Comparator {

public int compare(Object o1, Object o2) {
String name1 = ((Cat)o1).getName();
String name2 = ((Cat)o2).getName();

return name1.compareTo(name2);
}
}

----------------------------------------------------------------------------


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 20, 2004 9:59 am 
Expert
Expert

Joined: Sat Jan 17, 2004 2:57 pm
Posts: 329
Location: In the basement in my underwear
What does your equals and hashcode methods look like? It is your hashcode method that will determine a 'duplicate' in a HashSet not simply what you have defined as your PK.

This looks like a pure Java issue.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 21, 2004 11:24 pm 
Newbie

Joined: Tue Jan 06, 2004 8:06 am
Posts: 13
Acknowledged this is a java issue. I have double checked and still can't figure out what goes wrong.

I've tried setting hashCode() and equals() to getId() and getName() but results is always the same.

Anyone with sharp eye pls help points out my mistake.

Thx
-WK-

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


public class Cat implements Serializable {

private String id;
private String name;
private Cat parent;
private SortedSet children;
private Date modified;


public Cat(String name) {
this.name = name;
this.modified = Calendar.getInstance(java.util.Locale.US).getTime();
}

public Cat() {
}

public String getId() { return this.id; }
public void setId(String id) { this.id = id; }

public String getName() { return this.name; }
public void setName(String name) { this.name = name; }

public void setModified(Date u) { this.modified = u; }
public Date getModified() { return this.modified; }

public Cat getParent() { return this.parent; }
public void setParent(Cat c) { this.parent = c; }

public SortedSet getChildren() { return this.children; }
public void setChildren(SortedSet c) { this.children = c; }


///////////////////////////////////////////////////////////////////
public void addChild(Cat child) {
if(children == null) children = new TreeSet();

child.setParent(this);
children.add(child);
}

public boolean equals(Object other) {
if ( !(other instanceof Cat) ) return false;

Cat castOther = (Cat) other;
return new EqualsBuilder()
.append(this.getId(), castOther.getId())
.isEquals();
}

public int hashCode() {
return new HashCodeBuilder()
.append(getId())
.toHashCode();
}
}


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 21, 2004 11:25 pm 
Newbie

Joined: Tue Jan 06, 2004 8:06 am
Posts: 13
<class name="com.test.Cat" table="CAT">
<id name="id" column="ID" type="string" length="32">
<generator class="uuid.hex"/>
</id>

<version name="modified" column="MODIFIED" type="timestamp" unsaved-value="null" />

<property name="name" column="NAME" type="string" length="40"/>

<many-to-one name="parent" column="PARENT_ID" class="com.test.Cat" />

<set name="children" inverse="true" cascade="all" sort="com.test.CatNameComparator">
<key column="PARENT_ID"/>
<one-to-many class="com.test.Cat"/>
</set>

</class>


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 22, 2004 12:31 am 
Expert
Expert

Joined: Sat Jan 17, 2004 2:57 pm
Posts: 329
Location: In the basement in my underwear
Have you had a chance to read this yet?

http://www.hibernate.org/109.html

I would recommend reading this 3 times and then once you think you understand it, read it again.

2 weeks after you get what you think is an implementation, read it again since what you did still probably doesn't work :)

If I seem cynical it is because we have been trying to define a eq/hc that will work for us in all scenarios with not a whole lot of success.

Other than that have you tried tracing your hashcode method to see when it is getting called and what the id is at that point?

I had a fun scenario earlier this week where I was using an ID from a parent many to one in a composite primary key and serializing my object. Upon deserialization the child object was being added into the parent's hashset before the id was available and chaos ensued.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 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.