-->
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.  [ 1 post ] 
Author Message
 Post subject: Here is a way to map an EnumSet to a bitMask
PostPosted: Tue Jan 29, 2008 4:11 pm 
Newbie

Joined: Tue Nov 29, 2005 11:19 am
Posts: 3
I found a simple way to map an EnumSet directly to a bitMask/long value in DB :

When you do
Code:
message.setAllowedEnumSet(EnumSet.of(MyEnum.A,MyEnum.B,MyEnum.D));


In dB you end up with LongVal=11 (bitMask for MyEnum.A,MyEnum.B,MyEnum.D )

Here is the mapping :
* The allowedEnumSet field is transient because in fact it's mapped by the allowedBitMask long.

* It makes use of the hibernate annotation @AccessType("property") so hibernate uses the getters/setters for the allowedBitMask field.

* getAllowedBitMask and setAllowedBitMask methods are protected, so they do not pollute your domain model, they are just used by hibernate.

Code:
       @Transient   
   EnumSet<MyEnum> allowedEnumSet ;
   
   @Column(name = "allowed")
   @AccessType("property")
   private long allowedBitMask;
   
   protected long getAllowedBitMask(){
      return EnumHack.getElements(allowedEnumSet);
   }
   
   protected void setAllowedBitMask(long l){
      if (allowedEnumSet==null){
         allowedEnumSet= EnumSet.noneOf(MyEnum.class);
      }
      EnumHack.setElements(allowedEnumSet,l);
   }


And here is the EnumHack utility Class, making use of reflection to access the bitMask value inside of the EnumSet implementation.

This hack is necessary because java.util.RegularEnumSet is package protected and the elements Field is normally not accessible.

Code:
public class EnumHack {

   public static Long getElements(EnumSet enumSet) {

      // can't even use insanceOf, the class is package protected
      if ("RegularEnumSet".equals(enumSet.getClass().getSimpleName())) {
         try {
            Field elementsField = enumSet.getClass().getDeclaredField("elements");
            elementsField.setAccessible(true);
            return elementsField.getLong(enumSet);
         } catch (Exception e) {
            throw new RuntimeException(e);
         }
      } else {
         throw new UnsupportedOperationException("JumboEnumSet is not supported for now");
      }

   }
   
   public static void setElements(EnumSet enumSet,long l) {

      // can't even use insanceOf, the class is package protected
      if ("RegularEnumSet".equals(enumSet.getClass().getSimpleName())) {
         try {
            Field elementsField = enumSet.getClass().getDeclaredField("elements");
            elementsField.setAccessible(true);
            elementsField.setLong(enumSet,l);
         } catch (Exception e) {
            throw new RuntimeException(e);
         }
      } else {
         throw new UnsupportedOperationException("JumboEnumSet is not supported for now");
      }

   }

}


Of course this is a quick hack, not ready for production use ;)


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

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.