View Javadoc

1   package org.itracker.persistence.dao;
2   
3   import java.sql.PreparedStatement;
4   import java.sql.ResultSet;
5   import java.sql.SQLException;
6   import java.sql.Types;
7   import java.util.Properties;
8   
9   import org.apache.log4j.Logger;
10  import org.hibernate.HibernateException;
11  import org.itracker.model.IntCodeEnum;
12  
13  /**
14   * Custom Hibernate UserType to persist a Java 5 enum constant 
15   * that implement {@link org.itracker.model.IntCodeEnum } as an INTEGER
16   * using its integer code. 
17   * 
18   * <p>This should be preferred to using the enum.ordinal() or enum.name(). </p>
19   * 
20   * @author johnny
21   */
22  public class EnumCodeUserType extends AbstractEnumUserType {
23      
24      private static final int[] SQL_TYPES = { Types.SMALLINT };
25      private static final Logger log = Logger.getLogger(EnumCodeUserType.class);
26      /** Enum members, in the order they where declared. */
27      @SuppressWarnings("unchecked")
28  	private IntCodeEnum[] enumValues;
29      
30      /** 
31       * Default constructor, required by Hibernate. 
32       */
33      public EnumCodeUserType() {
34      }
35      
36      public void setParameterValues(Properties parameters) {
37          super.setParameterValues(parameters);
38          this.enumValues = (IntCodeEnum[]) this.enumClass.getEnumConstants();
39      }
40  
41      public Object nullSafeGet(ResultSet rs, String[] names,
42              Object owner) throws HibernateException, SQLException {
43          final int code = rs.getInt(names[0]);
44          
45          /* It is safe to assume there's always at least 1 enum constant
46           * because the compiler ensures that enums are never empty. 
47           * 
48           * Note : fromCode cannot be static in IntEnumCode ! 
49           */
50          try {
51          	return rs.wasNull() ? null : this.enumValues[0].fromCode(code);
52          } catch (Exception e) {
53          	log.info("nullSafeGet: failed to get default code enum, trying DEFAULT-code " + IntCodeEnum.DEFAULT_CODE, e);
54          	return this.enumValues[0].fromCode(IntCodeEnum.DEFAULT_CODE);
55          }
56      }
57  
58      public void nullSafeSet(PreparedStatement stmt, Object value,
59              int index) throws HibernateException, SQLException {
60          if (value == null) {
61              stmt.setNull(index, Types.INTEGER);
62          } else {
63              stmt.setInt(index, ((IntCodeEnum<?>) value).getCode());
64          }
65      }
66  
67      public int[] sqlTypes() {
68          return SQL_TYPES;
69      }
70  
71      public String objectToSQLString(Object value) {
72          return Integer.toString(((IntCodeEnum<?>) value).getCode());
73      }
74      
75      public String toXMLString(Object value) {
76          return objectToSQLString(value);
77      }
78      
79      public Object fromXMLString(String xmlValue) {
80          final int code;
81          
82          try {
83              code = Integer.parseInt(xmlValue);
84          } catch (NumberFormatException ex) {
85              throw new HibernateException(ex);
86          }
87          
88          /* It is safe to assume there's always at least 1 enum constant
89           * because the compiler ensures that enums are never empty. 
90           * 
91           * Note : fromCode cannot be static in IntEnumCode ! 
92           */
93          return this.enumValues[0].fromCode(code);
94      }
95      
96  }