[hibernate-issues] [Hibernate-JIRA] Updated: (ANN-161) Add support for custom code-based enums in EnumType - such as mapping ISO codes to gender Enums

Frederic Leitenberger (JIRA) noreply at atlassian.com
Wed May 21 14:27:33 EDT 2008


     [ http://opensource.atlassian.com/projects/hibernate/browse/ANN-161?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Frederic Leitenberger updated ANN-161:
--------------------------------------

    Attachment: MappedEnum.java.patch

Hello,

i have developed an integrated solution for the custom Enum mapping problem.
I created an Interface MappedEnum and modified the EnumType class accordingly.

Now it is possible to define a custom Enum dbValue-Mapping like this:

import org.hibernate.type.MappedEnum;

 public enum ExampleEnum implements MappedEnum {

     BLACK(100), //
     BLUE(200),
     RED(300),
     GREEN(400);

     private final int dbValue;

     private ExampleEnum(int dbValue) {
         this.dbValue = dbValue;
     }

     public int getDbValue() {
         return dbValue;
     }

}

I tested several scenarios:
1.) Saving an MappedEnum:
        Transaction tx = session.beginTransaction();
        try {
            TestEntity testEntity = new TestEntity();
            testEntity.setColor(ExampleEnum.BLUE);
            session.save(testEntity);
            tx.commit();
            System.out.println(testEntity);
        } catch (Exception e) {
            tx.rollback();
            throw e;
        }

2.) Loading an MappedEnum with Criteria and Restrictions.eq:
session.createCriteria(TestEntity.class).add(Restrictions.eq("color", ExampleEnum.BLUE));

3.) Loading an MappedEnum with Query and setParameter:
session.createQuery("from TestEntity where color = ?").setParameter(0, ExampleEnum.BLUE);

4.) Loading an MappedEnum with Query and the dbValue directly:
session.createQuery("from TestEntity where color = " + ExampleEnum.BLUE.getDbValue())

Everything worked fine.


The trick is to replace the ordinal-enum-mapping by the dbValue-enum-Mapping inside the EnumType-class if the MappedEnum-interface is implemented.
Therefore i replaced the internal array (which contained the enum-constants) by a HashMap.
This enables me to put in arbitrary numbers as key.
When the MappedEnum-interface is implemented the getDbValue() function for each constant is used to get the key.
If it is not implemented the ordinal-value is used (like before).

> Add support for custom code-based enums in EnumType - such as mapping ISO codes to gender Enums
> -----------------------------------------------------------------------------------------------
>
>                 Key: ANN-161
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/ANN-161
>             Project: Hibernate Annotations
>          Issue Type: Improvement
>          Components: binder
>    Affects Versions: 3.1beta6
>            Reporter: Leonardo Quijano
>            Priority: Minor
>         Attachments: MappedEnum.java.patch
>
>
> Now, this could be seen as an improvement to EnumType that's specific to a business domain, but I'm thinking it could help in the general case. Right now we can map JDK enums to several database types, such as INT, VARCHAR, etc. Each of these approaches have some drawbacks, depending on the domain:
> 1) The int mapping is not very reliable through refactorings. An enum that's mapped to a "0" or "2" integer value in the database could end up mapped as a different value if a future refactoring adds an additional enum with an ordinal of 0.
> 2) The varchar mapping could use the enum name instead of its ordinal. But again, if the enum changes, the mapping gets lost and it needs manual changes. It's also heavier on the performance side.
> A useful approach for enum mappings is to use common codes to represent them in the database. That depends of course of the domain logic that's being used. A useful example is the Human sex mapping, defined in ISO code 5218:
> http://en.wikipedia.org/wiki/ISO_5218
>     * 0 = not known,
>     * 1 = male,
>     * 2 = female,
>     * 9 = not specified.
> For this to work, the Sex enum could have a property "isoCode" that specifies the mapping between the database integer code and the Java enum. 
> For other domain examples additional examples could be specified.
> The EnumType could include a parameter that indicates the property to be evaluated for code-mapping, performing the translation in this way. Of course, reflection cache / byte-code generation / whatever could be specified to speed up the process.
> As always, patches are offered if you think this improvement is viable.

-- 
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