-->
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.  [ 6 posts ] 
Author Message
 Post subject: POJO's except Enumerated classes
PostPosted: Fri Oct 10, 2003 9:16 am 
Newbie

Joined: Fri Oct 10, 2003 8:53 am
Posts: 10
Location: Leeds, England
We have only just started using Hibernate, and everybody here has been completely bowled over by it. We are very enthusiastic converts!! :-)

I have a question however...

It seems to me that the major Hibernate strength is that the persistence layer is orthogonal to the POJOs that are to be persisted.

This appears to be true in all the cases that we are using, EXCEPT enumerated types, where one has to implement net.sf.hibernate.PersistentEnum in order to allow the type to be persisted. I.e. the enumerated type POJO (and the POJOs that use it) are 'polluted' by the need to import the hiberate class.

This can be worked around, by not implementing the interface, having the class contains a private member which is of type enumerated class, and then having public getters and setters on the enumerated type, and protected getters and setters (used by hibernate) which converts the enumerated type to an integer (a la net.sf.hibernate.PersistentEnum) which is then persisted.

That is, don't use net.sf.hibernate.PersistentEnum, and do it manually.

It seems to me though, that it migt be nice to be able to extract the persistence functionality that implements net.sf.hibernate.PersistentEnum into a decorator that can then be declared to decorate the Enumerated type in the hibernate mapping xml.

That way the POJOs only contain and refer to other POJOs, and the hibernate persistence functionality (as embodied by the net.sf.hibernate.PersistentEnum) can be implemented in another class, that can live on a different layer. That is, e.g. POJOs only available to web layer, POJO's + decorator available to business tier later...

I wonder what your thoughts on this might be...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 10, 2003 11:09 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
There is another (better) way. I use enums all over my system and not a single one implements PersistenceEnum.

Just define your own UserType that knows how to marshall/unmarshall your enums. This gives enormous flexibility as theses custom enums can be based on any type of persistent state (even strings or directly serialized) and the UserType becomes the single point in the system that deals with the conversion.


Top
 Profile  
 
 Post subject: POJO's except Enumerated classes
PostPosted: Fri Oct 10, 2003 12:07 pm 
Newbie

Joined: Fri Oct 10, 2003 8:53 am
Posts: 10
Location: Leeds, England
Could you explain the custom type mechanism to me. I've had a look at the reference doco, but I don't think I'm getting it.

Say I've got a class Car say, which has a colour property which is of type EnumColor.

The possible value values are "red", "green", "blue".

I want the integers 1, 2, 3 to represent those values in the database.

What do I have to write. I'm presuming some implementation of the Type interface, but...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 10, 2003 1:16 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Quote:
I'm presuming some implementation of the Type interface, but...

Actually, implement the UserType interface. Below is one of my UserType impls which handles an enum class named EligibilityLevel.

Code:
public class EligibilityLevelType
implements net.sf.hibernate.UserType, java.io.Serializable
{
    private static final Class CLAZZ = EligibilityLevel.class;
    private static final int[] SQL_TYPES = new int[] { java.sql.Types.INTEGER };
    private Logger log = Logger.getLogger( getClass() );

    public EligibilityLevelType()
    {
    }

    public Class returnedClass()
    {
        return CLAZZ ;
    }

    public int[] sqlTypes()
    {
        return SQL_TYPES ;
    }

    public boolean isMutable()
    {
        return false;
    }

    public Object deepCopy( Object obj )
    throws net.sf.hibernate.HibernateException
    {
        return obj;
    }
   
    public boolean equals( Object obj1, Object obj2 )
    throws net.sf.hibernate.HibernateException
    {
        if( obj1 == obj2 ) return true;
        if( obj1 == null || obj2 == null ) return false;

        return ((EligibilityLevel)obj1).equals( (EligibilityLevel)obj2 );
    }
   
    public Object nullSafeGet( java.sql.ResultSet resultSet, String[] names, Object owner )
    throws net.sf.hibernate.HibernateException, java.sql.SQLException
    {
        Integer value = (Integer)Hibernate.INTEGER.nullSafeGet( resultSet, names[0] );

        try
        {
            if (value == null)
                return null;
            else
                return EligibilityLevel.getEligibilityLevel( value.intValue() );
        }
        catch( Exception e )
        {
            log.warn( "Error resolving eligibility-level value [" + value + "] into eligibility-leve enum", e );
        }
        return null;
    }
   
    public void nullSafeSet( java.sql.PreparedStatement preparedStatement, Object obj, int index )
    throws net.sf.hibernate.HibernateException, java.sql.SQLException
    {
        EligibilityLevel level = (EligibilityLevel)obj;
        Hibernate.INTEGER.nullSafeSet( preparedStatement, new Integer(level.getValue()), index );
    }
   
}


Then in mappings, do:
Code:
    <property
        name="eligibilityLevel"
        type="EligibilityLevelType"
        column="elig_level"
    />

where the 'eligibilityLevel' property is of type EligibilityLevel...


Last edited by steve on Fri Oct 10, 2003 5:10 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 10, 2003 1:29 pm 
Newbie

Joined: Fri Oct 10, 2003 8:53 am
Posts: 10
Location: Leeds, England
Thanks very much !!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 10, 2003 9:45 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Fogot to mention, if you need to query against this attribute you need to set the parameter using Hibernate.custom(). E.g., I use:
Hibernate.custom(EligibilityLevelType.class)


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