2 Replies Latest reply on Sep 17, 2007 5:14 PM by fkifle

    @Enumerated with @ID Usage Issue

    fkifle

      I have an entity associated with an Oracle database table that has one column of type VarChar2(20) as the Primary Key which is used to store Java 1.5 enum values. The env. I am using is Jboss 4.1.2-GA as app server. I am getting an exception whenever I try to retrieve and store the values to another table. The enum, entity and exception follows:

      ----
      /**
      * List contains all Inspection Member Types
      */
      public enum InspectionPersonnelTypeEnum implements Serializable {

      AIRCREW("Air Crew Member"), INSPECTOR("Inspector"), MONITOR("Monitor");

      private String displayName;


      private InspectionPersonnelTypeEnum(String displayName) {
      this.displayName = displayName;
      }

      public String getDisplayName() {
      return displayName;
      }
      }

      ------

      @Entity
      @Table(name = "STR_INSP_PERSON_TYPE")
      public class InspectionPersonnelTypeEntityEJB implements Serializable {

      private InspectionPersonnelTypeEnum inspectionPersonType;

      @Id
      @Column(name = "INSPECTION_PERSON_TYPE"
      @Enumerated(value = EnumType.STRING)
      public InspectionPersonnelTypeEnum getInspectionPersonType() {
      return inspectionPersonType;
      }

      public void setInspectionPersonType(InspectionPersonnelTypeEnum inspectionPersonType) {
      this.inspectionPersonType = inspectionPersonType;
      }


      ------
      When trying to retrieve value from that column (e.g. populate the entity with a EntityManager.find()) I get the following exception:

      Caused by: org.hibernate.type.SerializationException: could not deserialize
      at org.hibernate.util.SerializationHelper.deserialize(SerializationHelper.java:217)
      at org.hibernate.util.SerializationHelper.deserialize(SerializationHelper.java:240)
      at org.hibernate.type.SerializableType.fromBytes(SerializableType.java:82)
      at org.hibernate.type.SerializableType.get(SerializableType.java:39)
      at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:163)
      at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:154)
      at org.hibernate.loader.Loader.getKeyFromResultSet(Loader.java:1097)
      at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:565)
      at org.hibernate.loader.Loader.doQuery(Loader.java:701)
      at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
      at org.hibernate.loader.Loader.loadCollection(Loader.java:1994)
      at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
      at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565)
      at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
      at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
      at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:454)
      at org.hibernate.engine.StatefulPersistenceContext.initializeNonLazyCollections(StatefulPersistenceContext.java:797)
      at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:241)
      at org.hibernate.loader.Loader.doList(Loader.java:2220)
      at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
      at org.hibernate.loader.Loader.list(Loader.java:2099)
      at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:378)
      at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
      at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
      at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
      at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
      at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:64)

      ----

      When I try to save a value stored in the table (@OneToMany
      @JoinTable(name = "STR_INSP_PERSON_ROLE",
      joinColumns = {@JoinColumn(name = "INSP_PERSON_ID")},
      inverseJoinColumns = {@JoinColumn(name = "INSPECTION_PERSON_TYPE")})
      public List getInspPersonTypes() {
      return this.inspPersonTypes;
      })
      I get the following exception:

      Caused by: java.sql.BatchUpdateException: ORA-12899: value too large for column "ACES_LIVE"."STR_INSP_PERSON_ROLE"."INSPECTION_PERSON_TYPE" (actual: 274, maximum: 20)
      at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
      at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10698)
      at org.jboss.resource.adapter.jdbc.WrappedStatement.executeBatch(WrappedStatement.java:519)
      at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
      at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)

      ---
      Is this a known issue? Any help would be most welcomed.

      Thanks
      Frezer

        • 1. Re: @Enumerated with @ID Usage Issue
          fkifle

          Correction: I am using 4.2.1GA version of Jboss.

          • 2. Re: @Enumerated with @ID Usage Issue
            fkifle

            Ok. I found a work around. I would really appreciate it if someone ran into the same issue and if they have solved it.
            I created enum wrapper class that extends hibernate UserType class:

            public class EnumVarcharUserType<E extends Enum<E>> implements UserType {
             private Class<E> clazz = null;
            
             protected EnumVarcharUserType(Class<E> c) {
             this.clazz = c;
             }
            
             private static final int[] SQL_TYPES = {Types.VARCHAR};
            
             public int[] sqlTypes() {
             return SQL_TYPES;
             }
            
             public Class returnedClass() {
             return clazz;
             }
            
             public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws
             HibernateException,
             SQLException {
             String name = resultSet.getString(names[0]);
             E result = null;
             if (!resultSet.wasNull()) {
             result = Enum.valueOf(clazz, name);
             }
             return result;
             }
            
             public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index)
             throws HibernateException, SQLException {
             if (null == value) {
             preparedStatement.setNull(index, Types.VARCHAR);
             }
             else if (value instanceof Enum) {
             preparedStatement.setString(index, ((Enum) value).name());
             }
             else if (value instanceof String) {
             preparedStatement.setString(index, (String) value);
             }
             }
            
             public Object deepCopy(Object value) throws HibernateException {
             return value;
             }
            
             public boolean isMutable() {
             return false;
             }
            
             public Object assemble(Serializable cached, Object owner) throws HibernateException {
             return cached;
             }
            
             public Serializable disassemble(Object value) throws HibernateException {
             return (Serializable) value;
             }
            
             public Object replace(Object original, Object target, Object owner) throws HibernateException {
             return original;
             }
            
             public int hashCode(Object x) throws HibernateException {
             return x.hashCode();
             }
            
             public boolean equals(Object x, Object y) throws HibernateException {
             if (x == y) {
             return true;
             }
             if (null == x || null == y) {
             return false;
             }
             return x.equals(y);
             }
            }
            
            --------------------------------
            public class InspectionPersonnelTypeUserType
             extends EnumVarcharUserType<InspectionPersonnelTypeEnum> {
             public InspectionPersonnelTypeUserType() {
             super(InspectionPersonnelTypeEnum.class);
             }
            

            So I replaced all instance of InspectionPersonnelTypeEnum with this new wrapped class InspectionPersonnelTypeUserType.