[hibernate-issues] [Hibernate-JIRA] Updated: (HHH-2991) Non public constructors cannot be used whith 'select new Object(...)' in HQL

Jaime Porras (JIRA) noreply at atlassian.com
Tue Dec 11 05:09:56 EST 2007


     [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-2991?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Jaime Porras updated HHH-2991:
------------------------------

    Attachment: hql-constructor-test.rar

Test case (Java + mappings).
Hibernate fails on startup beacause query check is enabled:

11-dic-2007 10:53:01 org.hibernate.hql.ast.ErrorCounter reportError
SEVERE:  Unable to locate appropriate constructor on class [test.hibernate.hqlconstructor.Name]
[cause=org.hibernate.PropertyNotFoundException: no appropriate constructor in class: test.hibernate.hqlconstructor.Name]
11-dic-2007 10:53:01 org.hibernate.impl.SessionFactoryImpl <init>
SEVERE: Error in named query: PersistedName.privateConstructor
org.hibernate.hql.ast.QuerySyntaxException: Unable to locate appropriate constructor on class [test.hibernate.hqlconstructor.Name] [
        
        select new test.hibernate.hqlconstructor.Name(name, surname) from
        test.hibernate.hqlconstructor.PersistedName
        
    ]


> Non public constructors cannot be used whith 'select new Object(...)' in HQL
> ----------------------------------------------------------------------------
>
>                 Key: HHH-2991
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2991
>             Project: Hibernate3
>          Issue Type: Bug
>          Components: query-hql
>    Affects Versions: 3.2.5
>         Environment: Hibernate 3.2.5
>            Reporter: Jaime Porras
>            Priority: Minor
>         Attachments: hql-constructor-test.rar, ReflectHelper.java
>
>   Original Estimate: 10 minutes
>  Remaining Estimate: 10 minutes
>
> Using following HQL
> <query name="family">
> <![CDATA[
> select new Family(mother, mate, offspr)
> from DomesticCat as mother
>    join mother.mate as mate
>    left join mother.kittens as offspr
> ]]>
> </query>
> with
> public class Family {
>    protected Family(String mother, String mate, String offspr) {
>        // code
>    }
> }
> Note: assuming Family constructor is correct (argument types are correct)
> During hql analyzing process, Hibernate produces the following error:
> SEVERE: Error in named query: family
> org.hibernate.hql.ast.QuerySyntaxException: Unable to locate appropriate constructor on class [Family] [
> select new Family(mother, mate, offspr)
> from DomesticCat as mother
>    join mother.mate as mate
>    left join mother.kittens as offspr
> ]
> This error is produced because Family constructor is protected (may be private). 
> org.hibernate.util.ReflectHelper is the class used to find the appropriate constructor. But the code used to do it calls clazz.getConstructors(), getting only the public contructors:
> public static Constructor getConstructor(Class clazz, Type[] types) throws PropertyNotFoundException {
> 		final Constructor[] candidates = clazz.getDeclaredConstructors(); // Get all constructors (public and not public)
> 		for ( int i=0; i<candidates.length; i++ ) {
> 			final Constructor constructor = candidates[i];
> 			final Class[] params = constructor.getParameterTypes();
> 			if ( params.length==types.length ) {
> 				boolean found = true;
> 				for ( int j=0; j<params.length; j++ ) {
> 					final boolean ok = params[j].isAssignableFrom( types[j].getReturnedClass() ) || (
> 						types[j] instanceof PrimitiveType &&
> 						params[j] == ( (PrimitiveType) types[j] ).getPrimitiveClass()
> 					);
> 					if (!ok) {
> 						found = false;
> 						break;
> 					}
> 				}
> 				if (found) {
> 					if ( !isPublic(clazz, constructor) ) constructor.setAccessible(true);
> 					return constructor;
> 				}
> 			}
> 		}
> 		throw new PropertyNotFoundException( "no appropriate constructor in class: " + clazz.getName() );
> }
> The only thing to do is change the first line by:
> final Constructor[] candidates = clazz.getDeclaredConstructors();
> PD:
> If only public constructors will be used the this code has no sense:
> 	if (found) {
> 		if ( !isPublic(clazz, constructor) ) constructor.setAccessible(true);
> 		return constructor;
> 	}

-- 
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
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the hibernate-issues mailing list