-->
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.  [ 9 posts ] 
Author Message
 Post subject: SortedSet ClassCastException and hbm2java, and set ordering
PostPosted: Fri Nov 21, 2003 3:25 pm 
Newbie

Joined: Thu Nov 20, 2003 2:58 pm
Posts: 11
Location: Seattle, Washington
I was getting a ClassCastException when I try to load a saved object.
It seems that Hibernate was trying to pass in a regular hibernate.Set instead of a SortedSet.

It seems that the order in which you list sets in the hbm file makes a difference when generating code. At least I find that all sets listed after a set that is sorted produce sorted sets in the generated code. But the hibernate core (correctly) doesn't do that. So it tries to pass in a regular set when the generated code is expecting a SortedSet.

Is this news? I did not find mention of it anywhere.

I'm using Hibernate 2.0.3 and the 2.0.2 extensions.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 21, 2003 3:28 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
POJO collection attributes have to be of interface type. This means you can have a:

private Set myChildren = new HashSet();
private List myOthers = new ArrayList();

but not this:

private TreeSet myChildren...

This is actually one of the few limitations with Hibernate and described in the documentation. I hope that this was what you asked for.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject: SortedSet ClassCastException and hbm2java, and set ordering
PostPosted: Fri Nov 21, 2003 5:25 pm 
Newbie

Joined: Thu Nov 20, 2003 2:58 pm
Posts: 11
Location: Seattle, Washington
thanks, but that isn't the problem.

The code generator is generating code that expects SortedSets even though the mapping doesn't call for them if the set mapping comes after a set mapping that is sorted.

Example (in pseudo-hbm :-)

<mapping>
<class name="SomeClass">
<set name="plainSet">
<one-to-many class="SomeOtherClass" />
</set>
<set name="sortedSet" sort="MySorter" >
<one-to-many class="YAClass" />
</set>
</class>
</mapping>

This generates

public class SomeClass
{
private Set plainSet; // plus Set-based getters and setters
private SortedSet sortedSet; // plus SortedSet-based getters and setters.
}

now, if I change the mapping:

<mapping>
<class name="SomeClass">
<set name="sortedSet" sort="MySorter" >
<one-to-many class="YAClass" />
</set>
<set name="plainSet">
<one-to-many class="SomeOtherClass" />
</set>
</class>
</mapping>


This generates

public class SomeClass
{
private SortedSet sortedSet; // plus SortedSet-based getters and setters.
private SortedSet plainSet; // plus SortedSet-based getters and setters.
}

However, the hibernate core correctly reads the hbm and tries to pass in a Set to the
setPlainSet() method which (in this case) is expecting a SortedSet, causing the ClassCastException.

So, I guess I'm saying this seems like a bug in the CodeGenerator.

-Linus


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 02, 2003 5:25 pm 
Newbie

Joined: Thu Nov 20, 2003 2:58 pm
Posts: 11
Location: Seattle, Washington
If anyone cares, I have a fix for the SortedSet problem I described.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 02, 2003 6:42 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
Please try to use the latest version of hbm2java - this should be fixed a loooong time ago ;)

(anyway - what's your fix ?)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 02, 2003 6:54 pm 
Newbie

Joined: Thu Nov 20, 2003 2:58 pm
Posts: 11
Location: Seattle, Washington
I am using extensions 2.0.2 which is what is listed as latest on the hibernate.org downloads page. Should I be using something else?

What was happening is that you were switching to a Sorted collection at the first mention of sort, and not switching back unless sort="unsorted" was explicitly stated.

My fix (I'll admit it's a hack, but so was yours (by your own admission. :-)

In ClassMapping doCollections():

String originalInterface = interfaceClass;
String originalImplementingClass = implementingClass;
String sorterClass = null;

[...]

// Small hack to switch over to sortedSet/sortedMap if sort is specified. (that is sort != unsorted)
String sort = collection.getAttributeValue("sort");
if ("unsorted".equals(sort) ||
"".equals(sort)) {
interfaceClass = originalInterface;
implementingClass = originalImplementingClass;
}
else {
if (!"natural".equals(sort)) {
sorterClass = sort;
}
if("map".equals(xmlName)) {
interfaceClass = SortedMap.class.getName();
implementingClass = TreeMap.class.getName();
} else if("set".equals(xmlName)) {
interfaceClass = SortedSet.class.getName();
implementingClass = TreeSet.class.getName();
}
}

[...]

// add an import and field for this collection
addImport(interfaceClassName);
if ( sorterClass != null )
{
this.sortClass = sorterClass;
addImport( sorterClass );
}

The bigger hack is that ClassMapping has a public member "sortClass" (above) that I access when generating code in my renderer so that I can generate code to create the collection. This is not a general solution, I admit. What I am trying to get was to make the
add<CollectionItem>() method generation work. You have it commented out.

I have made it work for me with the above hacks, but I'm currently having trouble getting the foreign class mappings for the collection items. This is largely due to me OO-oriented schema design wherein everything descends from a base DbObject class that has a bunch of stuff that every class wants to have. I'm sure I'm not doing it the Proper Way, and I'm about to give up and give in.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 02, 2003 6:58 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
hehe - never give up - there are always a way out ;)

It would really be great if you could post a patch to the JIRA (and maybe even also post a hbm.xml that shows this error - just for completeness).

Regarding the add<Collection> stuff then yes - it's hard to get the "other side" since it's not explicitly modelled as such in the hbm.xml.

But please show ya' current code - i might wanna start working on it ;)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 02, 2003 7:10 pm 
Newbie

Joined: Thu Nov 20, 2003 2:58 pm
Posts: 11
Location: Seattle, Washington
I suppose I can post something to JIRA. I've never done that before, but I'm sure I can figure it out...

WRT what I'm doing, maybe I could send you my hackup versions of ClassMapping, CodeGenerator, and BasicRenderer.

What I have working, at least for what I've tried so far, is:

given the mappings

<set name="attrs" table="StationAttrs" lazy="true"
cascade="all" >
<key column="stationId"/>
<composite-element class="&util_pkg;.DescribedProperty" >
<property name="name" type="string" />
<property name="value" type="string" />
<property name="description" type="string" />
</composite-element>
</set>

<set name="installedHardware"
lazy="true" inverse="true"
cascade="save-update" >
<key column="stationId" />
<one-to-many class="&isis_pkg;.InstalledHardware" />
</set>

<set name="stationLogEntries" lazy="true"
inverse="true" cascade="save-update"
sort="&sort_pkg;.LogSorter" >
<key column="stationId" />
<one-to-many class="&isis_pkg;.LogEntry" />
</set>

I get

public Set getAttrs() {
return this.attrs;
}

public void setAttrs(Set attrs) {
this.attrs = attrs;
}

public void addAttr(DescribedProperty aAttr) {
if ( null == this.getAttrs() )
setAttrs(new HashSet())
this.getAttrs().add(aAttr);
}

public Set getInstalledHardware() {
return this.installedHardware;
}

public void setInstalledHardware(Set installedHardware) {
this.installedHardware = installedHardware;
}

public void addInstalledHardware(InstalledHardware aInstalledHardware) {
if ( null == this.getInstalledHardware() )
setInstalledHardware(new HashSet())
this.getInstalledHardware().add(aInstalledHardware);
}
public SortedSet getStationLogEntries() {
return this.stationLogEntries;
}

public void setStationLogEntries(SortedSet stationLogEntries) {
this.stationLogEntries = stationLogEntries;
}

public void addStationLogEntry(LogEntry aStationLogEntry) {
if ( null == this.getStationLogEntries() )
setStationLogEntries(new TreeSet(new isis.LogSorter()))
this.getStationLogEntries().add(aStationLogEntry);
}


I'd like to be able to do the inverse relationship setting too.

The SortedSet problem was described in an earlier post. Did that make sense?

Thanks,
Linus
linus --> iris.washington.edu


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 02, 2003 7:29 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
please post them both as two seperate issues on the JIRA (and preferably as patches)

_________________
Max
Don't forget to rate


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