From: <leg...@at...> - 2003-10-29 01:58:51
|
Message: The following issue has been closed. Resolver: Gavin King Date: Tue, 28 Oct 2003 7:56 PM Finally fixed! :) --------------------------------------------------------------------- View the issue: http://opensource.atlassian.com/projects/hibernate/secure/ViewIssue.jspa?key=HB-97 Here is an overview of the issue: --------------------------------------------------------------------- Key: HB-97 Summary: enhancement to "select new" Type: Patch Status: Closed Priority: Major Resolution: FIXED Project: Hibernate2 Fix Fors: 2.1 beta 5 Versions: 2.0rc2 Assignee: Gavin King Reporter: Ian Booth Created: Thu, 22 May 2003 5:47 PM Updated: Tue, 28 Oct 2003 7:56 PM Description: I have implemented an enhancement to the feature of HQL which allows the following types of query: select new FooDTO(bar.id, foobar.id, bar.name) from Bar as bar join FooBar as foobar In the case where the construction arguments to FooDTO are numeric (eg assume id atributes above are longs), then the code inside the renderSQL() method of QueryTranslator.java looks for a constructor of the form FooDTO(long barId, long foobarId, String barName). However, if an outer join is used in the query ie select new FooDTO(bar.id, foobar.id, bar.name) from Bar as bar left join FooBar as foobar then foobar.id may be null and the current Hibernate code will fail with a null pointer exception. I have altered the code inside the renderSQL() method to first look for a constructor taking the proper object types for Numeric arguments and if this one can't be found, then it defaults to the current behavior. ie in the example above it looks for FooDTO(Long fooId, Long barId, String barName) and if this one can't be found it instead looks for FooDTO(long fooId, long barId, String barName) as before. The patch is to, the the renderSQL() method of QueryTranslator, replace <snip> Class[] classes = new Class[types.length]; for ( int i=0; i<types.length; i++ ) { if ( types[i]!=null ) classes[i] = (types[i] instanceof PrimitiveType) ? ( (PrimitiveType) types[i] ).getPrimitiveClass() : types[i].getReturnedClass(); } try { if (holderClass!=null) holderConstructor = holderClass.getConstructor(classes); } catch (NoSuchMethodException nsme) { throw new QueryException("could not find constructor for: " + holderClass.getName(), nsme); } <snip> with <snip> Class[] primitiveClasses = new Class[types.length]; Class[] classes = new Class[types.length]; for ( int i=0; i<types.length; i++ ) { if ( types[i]!=null ) primitiveClasses[i] = (types[i] instanceof PrimitiveType) ? ( (PrimitiveType) types[i] ).getPrimitiveClass() : types[i].getReturnedClass(); if ( types[i]!=null ) classes[i] = types[i].getReturnedClass(); } try { if (holderClass!=null) holderConstructor = holderClass.getConstructor(primitiveClasses); } catch (NoSuchMethodException nsmex) { try { if (holderClass!=null) holderConstructor = holderClass.getConstructor(classes); } catch (NoSuchMethodException nsme) { throw new QueryException("could not find constructor for: " + holderClass.getName(), nsme); } } <snip> I hope this feature can make it into 2.0 final cause I now rely on this feature quite a bit! --------------------------------------------------------------------- JIRA INFORMATION: 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 If you want more information on JIRA, or have a bug to report see: http://www.atlassian.com/software/jira |