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: uncanny deleting some element from sorted collection
PostPosted: Thu Mar 30, 2006 2:57 am 
Newbie

Joined: Thu Mar 30, 2006 2:54 am
Posts: 11
Hi,
I have mapped some class with Set collection. It is mapped as one-to-many like:
[b]
<set name="photos" table="R_AFACILITY_PHOTO" sort="natural" cascade="all,delete-orphan">
<key column="ID_AFACILITY"/>
<many-to-many column="ID_PHOTO" class="Photo" unique="true"/>
</set>
[b]

Class Photo contains variable "sorter" and implements Comparable<Photo> where it is compared
"sorter" value.

I have noticed when I added next two and more instances of Photo class and call saveOrUpdate()
usually first object within collection was deleted from database.
After extended probing I discover source od this mistery behaviour. Some elements are deleted
when I add new Photo instance which has variable "sorter" less then others objects within collection.
Setting greater this "sorter" value after adding this object into collection is inconsiderable.
When I added new object which has "sorter" value default set to MAX, it works fine - no elements
are deleted after saving a bean. Do you think it is a bug?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 31, 2006 1:24 am 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
Could be. It might also have something to do with your compareTo, equals and hashCode methods. Make sure that all three are correct, and that none of them use the database key, as that won't be set when you first put an item into the set.

Try putting some logging or printlns in your compareTo method, and see if objects that you're expecting to be sorted correctly are actually sorting the same.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 31, 2006 3:09 am 
Newbie

Joined: Thu Mar 30, 2006 2:54 am
Posts: 11
Well I don't override a methods equals(Object o) and hashCode(). I think it is only used compareTo(I) method defined by Comparable<I>. I'm not sure what do you thing "not using database key within comparing method". I must use field "sorter" that is also persisted within DB. My class Photo looks like:
public class Photo implements Comparable<Photo>, Cloneable
{
private int id;
private int sorter;
private String name;

public int getId()
{
return id;
}

protected void setId(int id)
{
this.id = id;
}

public int getSorter()
{
return sorter;
}

public void setSorter(int sorter)
{
this.sorter = sorter;
}

public String getName()
{
return name;
}

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

public int compareTo(Photo photo)
{
int c = sorter - photo.sorter;
return (c<0 ? -1 : (c==0 ? 0 : 1));
}

public Photo clone()
{
Photo photo = new Photo();

photo.name = name;

return photo;
}

public String toString()
{
return name;
}

}


mapping looks like:
<class name="Photo" table="T_PHOTO">
<id name="id"
column="ID" type="integer">
<generator class="native"/>
</id>
<property name="sorter"
column="SORTER" type="integer" not-null="true"/>
<property name="name"
column="NAME" type="string" length="50" not-null="true"/>
</class>


Top
 Profile  
 
 Post subject:
PostPosted: Sun Apr 02, 2006 5:37 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
Your compareTo method can return any negative or positive integer to show smaller-than or larger-than, so you can remove the ternary operator. "return c;" will do the job more efficiently, and it's easier to read.

You'll have to define a hashCode and equals method, as that's almost certainly what's causing the oddness. If photos can never have their name changed, then it'll be easy (name is the business key), otherwise you're in a pickle, because there's no business key in the class. You could switch to using an assigned key and use the database key as the business key, but you can't do that with your current mapping, because the id changes when you save a photo for the first time.

Also note that many-to-many mappings don't support cascade delete-orphan. You should either use a one-to-many mapping, or else change your cascade to just "all".


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 03, 2006 3:17 am 
Newbie

Joined: Thu Mar 30, 2006 2:54 am
Posts: 11
thanks I'll try override these methods. By the way my declaration of relation one-to-many is right because "unique=true" is specified (see hibernate specification at paragraph 8.3.1)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 03, 2006 5:30 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
many-to-many unique="true" may well be exactly what you're looking for, but it doesn't support the cascade="delete-orphan" option. The delete-orphan part of the cascade attribute won't do anything. Write a test case to see it in action: if you remove a photo from the set without deleting it explicitly, it will remain in the database and won't be deleted.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 05, 2006 3:41 am 
Newbie

Joined: Thu Mar 30, 2006 2:54 am
Posts: 11
I don't agree. I have mapped class Proprietor which contains Set<Facility> collection. Class Facility contains Set<Photo> collection. All collections are mapped as many-to-many with unique=true cascade="all,delete-orphan" (understanding as one-to-many relation). And when I have removed any Photo or Facility from Proprietor collections the "orphans" within DB are correctly deleted when I'll call saveOrUpdate(Proprietor).

Well I have tried implements these methods hashCode() and equals(Object) within class Photo, but nothing was changed. When I add 2 and more elements into collection, usually first element is deleted -> exactly deleted is record within relation table between parent-child (in this case R_AFACILITY_PHOTO)


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.