[hibernate-issues] [Hibernate-JIRA] Created: (HHH-2039) ListType.indexOf doesn't work with DOM4J entities
Alexander Kiel (JIRA)
noreply at atlassian.com
Wed Aug 30 09:47:24 EDT 2006
ListType.indexOf doesn't work with DOM4J entities
-------------------------------------------------
Key: HHH-2039
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2039
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.1.3
Environment: Hibernate 3.1.3, HSQLDB
Reporter: Alexander Kiel
I try to save a entity (DOM4J mode) which contains a list:
<multiple-choice-task id="1">
...
<choices>
<choice id="2">
<task task-ref="1"/>
...
</choice>
<choice id="3">
<task task-ref="1"/>
...
</choice>
</choices>
</multiple-choice-task>
Mappings:
<list name="choices" lazy="true" inverse="false" cascade="all-delete-orphan"
node="choices">
<key column="taskid" not-null="true"/>
<list-index column="index"/>
<one-to-many class="....Choice"/>
</list>
<class name="....Choice" table="choice" node="choice">
<id name="id" column="id" unsaved-value="null" node="@id">
<generator class="hilo"/>
</id>
<many-to-one name="task" insert="false" update="false"
node="task/@task-ref" embed-xml="false">
<column name="taskid" not-null="true"/>
</many-to-one>
...
</class>
If I save the multiple-choice-task with Hibernate 3.1.3 I get following
Exception:
java.lang.ClassCastException: org.dom4j.tree.DefaultElement
at org.hibernate.type.ListType.indexOf(ListType.java:49)
at org.hibernate.engine.StatefulPersistenceContext.getIndexInParent(StatefulPersistenceContext.java:1066)
at org.hibernate.engine.StatefulPersistenceContext.getIndexInOwner(StatefulPersistenceContext.java:1041)
at org.hibernate.property.IndexPropertyAccessor$IndexGetter.getForInsert(IndexPropertyAccessor.java:74)
at org.hibernate.tuple.AbstractEntityTuplizer.getPropertyValuesToInsert(AbstractEntityTuplizer.java:264)
at org.hibernate.persister.entity.AbstractEntityPersister.getPropertyValuesToInsert(AbstractEntityPersister.java:3331)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:244)
Sourcecode of ListType.indexOf:
public Object indexOf(Object collection, Object element) {
List list = (List) collection;
for ( int i=0; i<list.size(); i++ ) {
//TODO: proxies!
if ( list.get(i)==element ) return new Integer(i);
}
return null;
}
The problem is that the collection is in DOM4J mode a Element with doesn't
implement List. In my example collection is the <choices> Element and
element is one of the <choice> Elements.
I suggest following FIX:
public Object indexOf(Object collection, Object element) {
if (collection instanceof List) {
int index = ((List) collection).indexOf(element);
return index == -1 ? null : new Integer(index);
} else if (collection instanceof Element) {
int index = ((Element) collection).content().indexOf(element);
return index == -1 ? null : new Integer(index);
} else {
throw new IllegalArgumentException("collection type not supported.");
}
}
It works for me.
By the way:
Why bother with a own for loop and own comparison?
Because of equals()?
list.get(i) can be much more costly on non RandomAccess lists than an
unnessesary equals().
Please fix this issue in the next release. I have to work with the SVN Version
and my own fix until than. I have a production system to which I want to add
XML backup/restore.
Thanks.
Alexander Kiel
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
More information about the hibernate-issues
mailing list