Duplicate
Details
Assignee
Former userFormer user(Deactivated)Reporter
Jakub NarlochJakub NarlochLabels
Components
Affects versions
Priority
Major
Details
Details
Assignee
Former user
Former user(Deactivated)Reporter
Jakub Narloch
Jakub NarlochLabels
Components
Affects versions
Priority
Created August 6, 2014 at 9:47 PM
Updated April 22, 2015 at 9:14 PM
Resolved August 22, 2014 at 6:12 PM
According to JPA 2.1 specs: http://download.oracle.com/otndocs/jcp/persistence-2_1-fr-eval-spec/index.html
the orm.xml definiton of constructor-result should allow to specify the column type - through class attribute e.g.:
<sql-result-set-mapping name="XMLEmployeeConstructorResultSetMapping"> <constructor-result target-class="EmployeeDetails"> <column-result name="EMP_ID" class="Integer"/> <column-result name="F_NAME" class="String"/> <column-result name="L_NAME" class="String"/> <column-result name="R_COUNT" class="Integer"/> </constructor-result> </sql-result-set-mapping>
but the implementation apparently ignoes those values and always tries to map them based on the retrieved result set metadata
This leads to funny situation in which despite that one had provided explicit type mapping, recieves an exception thrown from ConstructorResultColumnProcessor that no matching constructor has been found, so without actually running the query for the first time I can not define the constructor that Hibernate will be able to invoke.
I'm not entirely familar with the Hibernate internalls, but that might seem not entirely portable accross diferent DBMS and JDBC drivers as for instance in one driver the result of COUNT() function can be mapped in int and in another into long. Preferebly the types that were defined in the mapping should take precedence and based on the the proper constructor should be resolved.
As long as I am concerned, the problem lays in implementation of ResultsetMappingSecondPass that never sets the mapped type, and always passes null:
for ( ConstructorResult constructorResult : ann.classes() ) { List<NativeSQLQueryScalarReturn> columnReturns = new ArrayList<NativeSQLQueryScalarReturn>(); for ( ColumnResult columnResult : constructorResult.columns() ) { columnReturns.add( new NativeSQLQueryScalarReturn( mappings.getObjectNameNormalizer().normalizeIdentifierQuoting( columnResult.name() ), null ) ); } definition.addQueryReturn( new NativeSQLQueryConstructorReturn( constructorResult.targetClass(), columnReturns ) ); }