-->
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.  [ 17 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: EnumSet mapping
PostPosted: Fri Nov 04, 2005 2:37 pm 
Newbie

Joined: Fri Oct 14, 2005 2:35 pm
Posts: 14
I've successfully mapped properties that are an enum type with the EnumUserType in the wiki. So now I'm wondering what the best method for mapping a property that is an EnumSet is in Hibernate.

I've got an enum and a class like the following:

Code:
public enum TermOffered {
    FALL, WINTER, SUMMER;
}

public class Course {   
    protected EnumSet<TermOffered> termsOffered;

    // get/set termsOffered
}


I could avoid the issue by using a plain Set instead of an EnumSet, but what I'd like is to see the EnumSet mapped to a single column in the database so there is no extra query needed to get the terms offered for the course. Any suggestions?

Thanks

Hibernate version:
3.0.5

Name and version of the database you are using:
MySQL 4.1.14


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 05, 2005 8:20 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Another UserType :)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 07, 2005 12:46 am 
Newbie

Joined: Fri Oct 14, 2005 2:35 pm
Posts: 14
That's what I thought but I'm not sure exactly where to begin. I'd like to just store whatever bit vector backs the EnumSet but don't see how I can get access to it. Any thoughts how to implement the UserType? Haven't really had much experience with them.


Top
 Profile  
 
 Post subject: EnumSet usertype?
PostPosted: Fri Jan 13, 2006 10:21 pm 
Beginner
Beginner

Joined: Fri May 06, 2005 2:37 pm
Posts: 39
Has anyone tried this implementation?

We've talked about translating an enumset into a bitmask for the database, but I'd love to see other ideas.


Top
 Profile  
 
 Post subject: EnumSet solution
PostPosted: Thu Apr 13, 2006 10:25 pm 
Beginner
Beginner

Joined: Fri May 06, 2005 2:37 pm
Posts: 39
Hopefully this will help someone.

To map an EnumSet (or any Set or Collection of Java 5 enums), just use Hibernate's <element column> feature. It works quite well, for loads, saves and queries. Here's a code example:

(in your Java class)
public enum TestAction {
MASTER_POOL, PRIMARY_POOLS, INDIV_SAMPLES, NONE
}

private Set<TestAction> requiredActions = EnumSet.noneOf( TestAction.class );

(in your class' .hbm.xml file)

<set name="requiredActions" table="required_action">
<key column="id" not-null="true"/>
<element column="action" type="testAction"/>
</set>

Your database table should have an id and string column.

Your query will look like: (this was the hard part for us)
"from MatrixTarget mt join mt.requiredActions actions where actions IN (?)"

and then pass in the enum you're looking for.


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 19, 2006 8:51 am 
Newbie

Joined: Thu Jan 13, 2005 10:04 am
Posts: 18
jasonab, this solution seems to be working for me - just one thing, how do I query for a set of enums with your example? If I use a query like the one you gave in your example and pass an ordinal value I get results, what I'd like to be able to do is pass over to the dao an EnumSet of my enum.


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 19, 2006 1:12 pm 
Beginner
Beginner

Joined: Fri May 06, 2005 2:37 pm
Posts: 39
Quote:
If I use a query like the one you gave in your example and pass an ordinal value I get results, what I'd like to be able to do is pass over to the dao an EnumSet of my enum.


Honestly, I'm not sure if that's possible with hibernate (or sql?) in general. I don't believe you can pass any type of collection into a query and expect it to work. You'll need a query that takes a specific number of parameters and set them individually from the set.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 25, 2006 2:09 pm 
Newbie

Joined: Fri Jun 23, 2006 1:36 pm
Posts: 2
You could use the HQL expression "IN ELEMENTS(<your EnumSet>)" to query against a collection.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 8:42 pm 
Beginner
Beginner

Joined: Mon Jun 19, 2006 4:10 pm
Posts: 27
I am confused here -- do I need to do all the MyEnumUserType stuff needed for mapping Enum types? Or if I want map just the enumset, this is good enough? thanx.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 9:03 pm 
Beginner
Beginner

Joined: Fri May 06, 2005 2:37 pm
Posts: 39
shrndegruv wrote:
I am confused here -- do I need to do all the MyEnumUserType stuff needed for mapping Enum types? Or if I want map just the enumset, this is good enough? thanx.


If the enum is only persisted as part of the set, the set mapping is sufficient.

If you ever want to save the enum as an independent field, you'll need the enum usertype.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 9:35 pm 
Beginner
Beginner

Joined: Mon Jun 19, 2006 4:10 pm
Posts: 27
jason

can you post the full example, not just snippets? thanx


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 9:45 pm 
Beginner
Beginner

Joined: Fri May 06, 2005 2:37 pm
Posts: 39
shrndegruv wrote:
jason

can you post the full example, not just snippets? thanx


For the EnumSet mapping? What you see if the full example from the hibernate perspective. You just need a table in your database that takes the string and has a foreign key (to map the collection).

Sorry, I can't post the full class file.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 10:51 pm 
Beginner
Beginner

Joined: Mon Jun 19, 2006 4:10 pm
Posts: 27
jason

do I need a mapping for the Enum Type?
edit: no
edit: I thought it was working but its broxed. Im getting class cast exception on my Enumeration type. In your mapping snippet the element column has type of the Enum, should it be string?
Also, should the element column type be String or my Enum type?
edit: yes

when you say
private Set<TestAction> requiredActions = EnumSet.noneOf( TestAction.class );

in the general case, create a Set on the class that holds the EnumSet, and when the Set of enum types get hydrated, have the setter recreate the EnumSet?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 25, 2006 2:24 pm 
Beginner
Beginner

Joined: Fri May 06, 2005 2:37 pm
Posts: 39
shrndegruv wrote:
jason

do I need a mapping for the Enum Type?
edit: no


Unfortuately, I did forget about that. You will need some sort of usertype to map the enum to a string, either the standard Hibernate type or one of your own doing.

Here's how the type is mapped for the EnumSet:
Code:
<typedef class="com.mainpnt.lis.orm.EnumUserType" name="testAction">
    <param name="enumClassName">
      com.mainpnt.lis.pooling.domain.MatrixTarget$TestAction
    </param>
  </typedef>


shrndegruv wrote:
Also, should the element column type be String or my Enum type?
edit: yes


The type you save into the database should be a string.

shrndegruv wrote:
when you say
private Set<TestAction> requiredActions = EnumSet.noneOf( TestAction.class );

in the general case, create a Set on the class that holds the EnumSet, and when the Set of enum types get hydrated, have the setter recreate the EnumSet?


You want to create a set of Enums, since that's presumably what matters, and what you want to persist. TestAction is an enum (you can see that in my first post). When the set is loaded, the EnumUserType transforms the strings into the enums.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 25, 2006 2:32 pm 
Beginner
Beginner

Joined: Mon Jun 19, 2006 4:10 pm
Posts: 27
Quote:
<set name="requiredActions" table="required_action">
<key column="id" not-null="true"/>
<element column="action" type="testAction"/>
</set>


jason thanx for trying to help here.

so the type="testAction" maps to the typedef you defined above? And I *will* have to define a UserType (as discussed elsewhere)?

Question: wouldn't it be better to just maintain a Set<String> that gets updated to reflect the EnumSet when appriopriate, and persist that?

I think this is a huge anti-pattern. Hibernate specific code is creeping into my application above the dao layer. Hibernate is wonderful and can save a bunch of time, but I think this particular aspect is a bit weak....


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 17 posts ]  Go to page 1, 2  Next

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.