I was doing some queries today in EJB-QL on JBossAS (which uses Hibernate as persistence provider).
And for a query that was nicely working in the Jopr Gui, I got errors in the test suite:
javax.ejb.EJBTransactionRolledbackException: java.lang.IllegalArgumentException: org.hibernate.QueryException: could not instantiate: com.acme.Foo
at ...... ( a lot ) ....
Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryException: could not instantiate: com.acme.Foo
Ok nice - Hibernate can not instantiate my class because it can not instantiate my class. So what?
After looking some time at this and debugging around I found out that the issue was the following. But before I show you the code, let me assure that IntelliJ flagged it as valid and it did work in the UI.
But now the code:
SELECT new com.acme.FOO(res.name, res.id, ... , parent.name, parent.id)
FROM Resource res
LEFT OUTER JOIN res.parentResource parent
...
WHERE ...
The constructor of com.acme.Foo
looked like this:
Foo(String res.name, int res.id, ... , String parentName, int parentId) {}
This is all valid,
but:
It can happen for Resources at the root of the hierarchy to not have a parent (when they are roots). And in this case, parent is null
and Hibernate is looking for a constructor to pass NULL
in as last argument, which does not fit for 'int
'. Thus the failure to instantiate the class.
The correct constrctor looks like this:
Foo(String res.name, int res.id, ... , String parentName, Integer parentId) {}
(of course you need to update the respective property within Foo too).
Conclusion:
Just to get it straight: Hibernate is doing the right thing - it's only not easy to find out what is going wrong.