-->
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.  [ 3 posts ] 
Author Message
 Post subject: How to map a parameterized UserType as a collection element?
PostPosted: Thu Jun 30, 2005 3:04 pm 
Beginner
Beginner

Joined: Thu Nov 06, 2003 7:27 pm
Posts: 30
Location: Minneapolis, MN, USA
I (like half the developers on earth, it seems) have a UserType for mapping org.apache.commons.lang.enums.Enum. It is a parameterized user type, which I typically use like this:

Code:
public class MonkeyColor extends Enum {
    ...
}

public class Monkey {
    private MonkeyColor color;
    ...
}

<property name="color">
    <type name="org.mpr.common.persistence.hibernate.EnumType">
        <param name="enumClass">org.mpr.monkeyapp.model.MonkeyColor</param>
    </type>
</property>


Yes, yes, I know -- I'd rather be using Java's enum facility, and Hibernate will eventually support than in all sorts of fancy ways. But right now we're stuck on 1.4.2 on our production servers. :(

Anyway, suppose I want to have a multicolored monkey. My class would then look like:

Code:
public class Monkey {
    private Set<MonkeyColor> color;
    ...
}


And I'd really want to map it like this:

Code:
<set name="availableColors" table="monkeyColors">
        <key column="monkeyId"/>
        <element>
            <type name="org.mpr.common.persistence.hibernate.EnumType">
                <param name="enumClass">org.mpr.monkeyapp.model.MonkeyColor</param>
            </type>
        </element>
</set>


But according to the mapping file DTD, I can't do that, because "type" is only allowable as an attribute of "element", not as a nested subelement:

Code:
<!ELEMENT element (column|formula)*>
    <!ATTLIST element column CDATA #IMPLIED>
    <!ATTLIST element node CDATA #IMPLIED>
    <!ATTLIST element formula CDATA #IMPLIED>
    <!ATTLIST element type CDATA #REQUIRED>
    <!ATTLIST element length CDATA #IMPLIED>
    <!ATTLIST element precision CDATA #IMPLIED>
    <!ATTLIST element scale CDATA #IMPLIED>
    <!ATTLIST element not-null (true|false) "false">
    <!ATTLIST element unique (true|false) "false">


Is this just a missing feature in the DTD? Or does Hibernate not support a collection of parameterized user types at all?

I dug around on the web a bit, but couldn't find any info about this question.

Hibernate version: 3.0.5

My EnumType class, FWIW:

Code:
package org.mpr.common.persistence.hibernate;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Properties;

import org.apache.commons.lang.enums.Enum;
import org.apache.commons.lang.enums.EnumUtils;
import org.hibernate.HibernateException;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;


public class EnumType implements UserType, ParameterizedType {
    public static final int[] SQL_TYPES = new int[]{ Types.VARCHAR };
    private Class enumClass;
   
    public int[] sqlTypes() {
        return SQL_TYPES;
    }
   
    public void setParameterValues(Properties parameters) {
        String enumClassName = parameters.getProperty("enumClass");
        try {
            enumClass = Class.forName(enumClassName);
        } catch (ClassNotFoundException e) {
            throw new HibernateException("Class " + enumClassName + " not found ", e);
        }
        if(!Enum.class.isAssignableFrom(enumClass))
            throw new HibernateException(enumClass + " does not extend " + Enum.class);
    }
       
    public Class returnedClass() {
        return enumClass;
    }

    public boolean equals(Object x, Object y) throws HibernateException {
        return (x == y);
    }

    public int hashCode(Object x) throws HibernateException {
        return x.hashCode();
    }

    public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
        String name = rs.getString(names[0]);
        return rs.wasNull() ? null : EnumUtils.getEnum(enumClass, name);
    }

    public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
        if (value == null) {
            st.setNull(index, Types.INTEGER);
        } else {
            st.setString(index, ((Enum)value).getName());
        }
    }

    public Object deepCopy(Object value) throws HibernateException {
        return value;
    }

    public boolean isMutable() {
        return false;
    }

    public Serializable disassemble(Object value) throws HibernateException {
        return (Serializable) value;
    }

    public Object assemble(Serializable cached, Object owner) throws HibernateException {
        return cached;
    }

    public Object replace(Object original, Object target, Object owner) throws HibernateException {
        return original;
    }
}



Top
 Profile  
 
 Post subject: Huh.
PostPosted: Thu Jun 30, 2005 3:34 pm 
Beginner
Beginner

Joined: Thu Nov 06, 2003 7:27 pm
Posts: 30
Location: Minneapolis, MN, USA
Fascinating.

If I edit the DTD to allow the desired syntax...

Code:
<!ELEMENT element (column|formula|type)*>
   <!ATTLIST element type CDATA #IMPLIED>

...it already works!

So apparently this is nothing more than an oversight in the DTD. Should I submit this as a bug? An improvement request? I know Gavin and the team are super touchy about how and where requests are submitted, and I don't fully understand their process.... Any advice is welcome.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 30, 2005 5:42 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Sure, submit a patch to JIRA.


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