Uploaded image for project: 'Hibernate ORM'
  1. HHH-10766

XML Enum mapping with parameter 'type'

    Details

      Description

      Hello,
      I was migrating from hibernate-core 4.3.11 to 5.1.0

      I had this Hibernate XML mapping:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
              "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
      
      <hibernate-mapping default-access="field" package="org.libreplan.entities">
      <class name="CalendarException" table="calendar_exception_type">
              <id name="id" access="property" type="long">
                  <generator class="increment">
                      <param name="max_lo">100</param>
                  </generator>
              </id>
      <property name="color">
                  <type name="org.hibernate.type.EnumType">
                      <param name="enumClass">org.libreplan.entities.CalendarExceptionColor</param>
                      <param name="type">12</param>
                  </type>
              </property>
      </class>
      </hibernate-mapping>
      

      After I started jetty, hibernate started to validate my schema and throws an exception:

      Caused by: 
      org.hibernate.tool.schema.spi.SchemaManagementException: 
      Schema-validation: wrong column type encountered in column [color] 
      in table [calendar_exception]; 
      found [varchar (Types#VARCHAR)], but expecting [int4 (Types#INTEGER)]
      

      I was curious why it was expecting SQLType 4 (Integer) instead of SQLType 12 (Varchar). On version 4.3.11 it works perfect.

      I checked out hibernate-core 5.1.0 sources and found source of problem:

      private EnumValueMapper interpretParameters(Properties parameters) {
      		if ( parameters.containsKey( NAMED ) ) {
      			final boolean useNamed = ConfigurationHelper.getBoolean( NAMED, parameters );
      			if ( useNamed ) {
      				return new NamedEnumValueMapper();
      			}
      			else {
      				return new OrdinalEnumValueMapper();
      			}
      		}
      
      		if ( parameters.containsKey( TYPE ) ) {
      			final int type = Integer.decode( (String) parameters.get( TYPE ) );
      			if ( isNumericType( type ) ) {
      				return new OrdinalEnumValueMapper();
      			}
      			else if ( isCharacterType( type ) ) {
      				return new OrdinalEnumValueMapper();
      			}
      			else {
      				throw new HibernateException(
      						String.format(
      								Locale.ENGLISH,
      								"Passed JDBC type code [%s] not recognized as numeric nor character",
      								type
      						)
      				);
      			}
      		}
      
      		// the fallback
      		return new OrdinalEnumValueMapper();
      	}
      

      My mapping passed here with 2 parameters (enumClass and type).
      Code handled it correct, it found that parameters contains 'type', but the problem is
      that after both if statements it returns OrdinalEnumValueMapper.
      Which is for if statement: isCharacterType( type ) incorrect. Should be NamedEnumValueMapper, (look at containsKey( NAMED ) handler, it works good).

        Attachments

          Activity

            People

            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Time Tracking

                Estimated:
                Original Estimate - 16h
                16h
                Remaining:
                Remaining Estimate - 16h
                16h
                Logged:
                Time Spent - Not Specified
                Not Specified