[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