You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Tobias Trelle <to...@codecentric.de> on 2011/03/30 12:22:56 UTC

NPE with Fetch Join Query

Hi,

I have a lazy loading 1:n association. I'd like to write a query to eager
fetch that association on demand.


@Entity
@NamedQueries(@NamedQuery(name = "fetchB", query = "SELECT a from A a LEFT
JOIN FETCH a.b WHERE a.id = :id"))
public class A {

    @Id
    private long id;

    private String name;

    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "FIRMA_ID")
    private Collection b;
    ...

@Entity
public class B {

    @Id
    private long id;

    private String name;
   ...



When I execute the named query ...


A a = em.createNamedQuery("fetchB", A.class).setParameter("id",
42).getSingleResult();


... the following SQL statement is executed against the database:

SELECT t0.id, t0.name, t1.FIRMA_ID, t1.id, t1.name 
    FROM S.A t0 LEFT OUTER JOIN S.B t1 ON t0.id = t1.FIRMA_ID 
    WHERE (t0.id = ?) optimize for 1 row 

If I execute it with my favourite SQL tool, I get a result set of size 2.

OpenJPA throws a NullpointerException:


 org.apache.openjpa.persistence.PersistenceException: null
FailedObject: SELECT a from A a LEFT JOIN FETCH a.b WHERE a.id = :id
[java.lang.String]
	at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:986)
	at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:885)
	at
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:1030)
	at org.apache.openjpa.jdbc.sql.AbstractResult.load(AbstractResult.java:280)
	at
org.apache.openjpa.jdbc.sql.SelectImpl$SelectResult.load(SelectImpl.java:2344)
	at org.apache.openjpa.jdbc.sql.AbstractResult.load(AbstractResult.java:274)
	at
org.apache.openjpa.jdbc.kernel.InstanceResultObjectProvider.getResultObject(InstanceResultObjectProvider.java:59)
	at org.apache.openjpa.lib.rop.EagerResultList.(EagerResultList.java:36)
	at org.apache.openjpa.kernel.QueryImpl.toResult(QueryImpl.java:1246)
	at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:1005)
	at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:861)
	at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:792)
	at
org.apache.openjpa.kernel.DelegatingQuery.execute(DelegatingQuery.java:542)
	at org.apache.openjpa.persistence.QueryImpl.execute(QueryImpl.java:288)
	at
org.apache.openjpa.persistence.QueryImpl.getResultList(QueryImpl.java:302)
	at
org.apache.openjpa.persistence.QueryImpl.getSingleResult(QueryImpl.java:326)
	at 
JpaFetchTestManual.testFindQuery(JpaFetchTestManual.java:58)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:585)
	at junit.framework.TestCase.runTest(TestCase.java:168)
	at junit.framework.TestCase.runBare(TestCase.java:134)
	at junit.framework.TestResult$1.protect(TestResult.java:110)
	at junit.framework.TestResult.runProtected(TestResult.java:128)
	at junit.framework.TestResult.run(TestResult.java:113)
	at junit.framework.TestCase.run(TestCase.java:124)
	at junit.framework.TestSuite.runTest(TestSuite.java:232)
	at junit.framework.TestSuite.run(TestSuite.java:227)
	at
org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
	at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
	at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
	at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
	at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
	at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.lang.NullPointerException
	at
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.setInverseRelation(JDBCStoreManager.java:469)
	at
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initializeState(JDBCStoreManager.java:429)
	at
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initialize(JDBCStoreManager.java:322)
	at
org.apache.openjpa.kernel.DelegatingStoreManager.initialize(DelegatingStoreManager.java:112)
	at
org.apache.openjpa.kernel.ROPStoreManager.initialize(ROPStoreManager.java:57)
	at org.apache.openjpa.kernel.BrokerImpl.initialize(BrokerImpl.java:1005)
	at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:963)
	... 35 more


What can be wrong with this simple example? Did I miss something?

Cheers,
Tobias

--
View this message in context: http://openjpa.208410.n2.nabble.com/NPE-with-Fetch-Join-Query-tp6222526p6222526.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: NPE with Fetch Join Query

Posted by Tobias Trelle <to...@codecentric.de>.
Rick Curtis wrote:
> 
> It looks like you configured openjpa.RuntimeUnenhancedClasses=true and I'm
> certain is your problem. Please configure another method of
> enhancement[1]... Let me know if you have any issues getting your classes
> enhanced.
> 

Thank you very much. It was indeed a matter of enhancement. Now my tests run
both with JDK1.6 (auto enhancement) and JDK1.5 using the -javaagent VM
parameter.

However, when using JDK 1.5 with javaagent, I am not able to use an own
classloader to redirect the resource persistence.xml to another file.
Typically, we are using a seperate persistence.xml per unit test, like
fetch-test-persistence.xml. That classloader ist attach to the current
thread ...


Thread.currentThread().setContextClassLoader(new
PersistenceXmlCustomClassLoader("fetch-test-persistence.xml"));


... and redirects to the given resource when it encounters a request for
persistence.xml. That happens _before_ the first access to
EntityManagerFactory and EntityManager.

I suppose the enhancer agent is triggered before that classloader is
registered with the thread and therefore the enhancer only sees the entities
in the standard persistence.xml.

Cheers,
Tobias


--
View this message in context: http://openjpa.208410.n2.nabble.com/NPE-with-Fetch-Join-Query-tp6222526p6237536.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: NPE with Fetch Join Query

Posted by Rick Curtis <cu...@gmail.com>.
Tobias -

> INFO 07:11:27 - Creating subclass for "[class
com.provinzial.framework.util.db.jpa.fetch.B, class
com.provinzial.framework.util.db.jpa.fetch.A]". This means that your
application will be less efficient ....

It looks like you configured openjpa.RuntimeUnenhancedClasses=true and I'm
certain is your problem. Please configure another method of
enhancement[1]... Let me know if you have any issues getting your classes
enhanced.

Thanks,
Rick

[1] http://openjpa.apache.org/entity-enhancement.html

On Thu, Mar 31, 2011 at 12:18 AM, Tobias Trelle <
tobias.trelle@codecentric.de> wrote:

> Hi Michael,
>
>
> Michael Dick wrote:
> >
> > Which version of OpenJPA are you using?
> >
>
> I'm using OpenJPA 2.0.1. The database ist DB2 V9. JPA startup log looks
> like:
>
>
>  INFO 07:11:27 - Using dictionary class
> "org.apache.openjpa.jdbc.sql.DB2Dictionary".
>  INFO 07:11:27 - Creating subclass for "[class
> com.provinzial.framework.util.db.jpa.fetch.B, class
> com.provinzial.framework.util.db.jpa.fetch.A]".
> This means that your application will be less efficient and will consume
> more memory than it would if
> you ran the OpenJPA enhancer. Additionally, lazy loading will not be
> available for one-to-one and
> many-to-one persistent attributes in types using field access; they will be
> loaded eagerly instead.
>  INFO 07:11:27 - Starting OpenJPA 2.0.1
> ...
>
>
>
> Michael Dick wrote:
> >
> > It looks like we don't have a cached version of the metadata for type B,
> > enabling
> > preloading&lt;
> http://openjpa.apache.org/builds/latest/docs/manual/manual.html#ref_guide_meta_repository&gt
> ;
> > of
> > the meta data might at least work around the problem.
> >
>
> Thanks for that hint, but it does not solve the problem.
>
> Even when I change the fetch type of the b association the eager and load
> the A entity by primary key, the error remains the same.
>
> My persistence.xml looks like this:
>
>
>
>                com.provinzial.framework.util.db.jpa.fetch.A
>                com.provinzial.framework.util.db.jpa.fetch.B
>                true
>

Re: NPE with Fetch Join Query

Posted by Tobias Trelle <to...@codecentric.de>.
Hi Michael,


Michael Dick wrote:
> 
> Which version of OpenJPA are you using?
> 

I'm using OpenJPA 2.0.1. The database ist DB2 V9. JPA startup log looks
like:


 INFO 07:11:27 - Using dictionary class
"org.apache.openjpa.jdbc.sql.DB2Dictionary".
 INFO 07:11:27 - Creating subclass for "[class
com.provinzial.framework.util.db.jpa.fetch.B, class
com.provinzial.framework.util.db.jpa.fetch.A]". 
This means that your application will be less efficient and will consume
more memory than it would if 
you ran the OpenJPA enhancer. Additionally, lazy loading will not be
available for one-to-one and 
many-to-one persistent attributes in types using field access; they will be
loaded eagerly instead.
 INFO 07:11:27 - Starting OpenJPA 2.0.1
...



Michael Dick wrote:
> 
> It looks like we don't have a cached version of the metadata for type B,
> enabling
> preloading&lt;http://openjpa.apache.org/builds/latest/docs/manual/manual.html#ref_guide_meta_repository&gt;
> of
> the meta data might at least work around the problem.
> 

Thanks for that hint, but it does not solve the problem.

Even when I change the fetch type of the b association the eager and load
the A entity by primary key, the error remains the same.

My persistence.xml looks like this:


	
		com.provinzial.framework.util.db.jpa.fetch.A
		com.provinzial.framework.util.db.jpa.fetch.B
		true

		
			
			
			
			
			

			
			
			

		
	


Cheers,
Tobias

--
View this message in context: http://openjpa.208410.n2.nabble.com/NPE-with-Fetch-Join-Query-tp6222526p6225913.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: NPE with Fetch Join Query

Posted by Michael Dick <mi...@gmail.com>.
Hi Tobias,

Which version of OpenJPA are you using?

It looks like we don't have a cached version of the metadata for type B,
enabling preloading<http://openjpa.apache.org/builds/latest/docs/manual/manual.html#ref_guide_meta_repository>of
the meta data might at least work around the problem.

-mike

On Wed, Mar 30, 2011 at 5:22 AM, Tobias Trelle <tobias.trelle@codecentric.de
> wrote:

> Hi,
>
> I have a lazy loading 1:n association. I'd like to write a query to eager
> fetch that association on demand.
>
>
> @Entity
> @NamedQueries(@NamedQuery(name = "fetchB", query = "SELECT a from A a LEFT
> JOIN FETCH a.b WHERE a.id = :id"))
> public class A {
>
>    @Id
>    private long id;
>
>    private String name;
>
>    @OneToMany(fetch = FetchType.LAZY)
>    @JoinColumn(name = "FIRMA_ID")
>    private Collection b;
>    ...
>
> @Entity
> public class B {
>
>    @Id
>    private long id;
>
>    private String name;
>   ...
>
>
>
> When I execute the named query ...
>
>
> A a = em.createNamedQuery("fetchB", A.class).setParameter("id",
> 42).getSingleResult();
>
>
> ... the following SQL statement is executed against the database:
>
> SELECT t0.id, t0.name, t1.FIRMA_ID, t1.id, t1.name
>    FROM S.A t0 LEFT OUTER JOIN S.B t1 ON t0.id = t1.FIRMA_ID
>    WHERE (t0.id = ?) optimize for 1 row
>
> If I execute it with my favourite SQL tool, I get a result set of size 2.
>
> OpenJPA throws a NullpointerException:
>
>
>  org.apache.openjpa.persistence.PersistenceException: null
> FailedObject: SELECT a from A a LEFT JOIN FETCH a.b WHERE a.id = :id
> [java.lang.String]
>        at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:986)
>        at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:885)
>        at
>
> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:1030)
>        at
> org.apache.openjpa.jdbc.sql.AbstractResult.load(AbstractResult.java:280)
>        at
>
> org.apache.openjpa.jdbc.sql.SelectImpl$SelectResult.load(SelectImpl.java:2344)
>        at
> org.apache.openjpa.jdbc.sql.AbstractResult.load(AbstractResult.java:274)
>        at
>
> org.apache.openjpa.jdbc.kernel.InstanceResultObjectProvider.getResultObject(InstanceResultObjectProvider.java:59)
>        at
> org.apache.openjpa.lib.rop.EagerResultList.(EagerResultList.java:36)
>        at org.apache.openjpa.kernel.QueryImpl.toResult(QueryImpl.java:1246)
>        at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:1005)
>        at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:861)
>        at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:792)
>        at
> org.apache.openjpa.kernel.DelegatingQuery.execute(DelegatingQuery.java:542)
>        at
> org.apache.openjpa.persistence.QueryImpl.execute(QueryImpl.java:288)
>        at
> org.apache.openjpa.persistence.QueryImpl.getResultList(QueryImpl.java:302)
>        at
>
> org.apache.openjpa.persistence.QueryImpl.getSingleResult(QueryImpl.java:326)
>        at
> JpaFetchTestManual.testFindQuery(JpaFetchTestManual.java:58)
>        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>        at
>
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>        at
>
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>        at java.lang.reflect.Method.invoke(Method.java:585)
>        at junit.framework.TestCase.runTest(TestCase.java:168)
>        at junit.framework.TestCase.runBare(TestCase.java:134)
>        at junit.framework.TestResult$1.protect(TestResult.java:110)
>        at junit.framework.TestResult.runProtected(TestResult.java:128)
>        at junit.framework.TestResult.run(TestResult.java:113)
>        at junit.framework.TestCase.run(TestCase.java:124)
>        at junit.framework.TestSuite.runTest(TestSuite.java:232)
>        at junit.framework.TestSuite.run(TestSuite.java:227)
>        at
>
> org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
>        at
>
> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
>        at
>
> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
>        at
>
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
>        at
>
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
>        at
>
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
>        at
>
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
> Caused by: java.lang.NullPointerException
>        at
>
> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.setInverseRelation(JDBCStoreManager.java:469)
>        at
>
> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initializeState(JDBCStoreManager.java:429)
>        at
>
> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initialize(JDBCStoreManager.java:322)
>        at
>
> org.apache.openjpa.kernel.DelegatingStoreManager.initialize(DelegatingStoreManager.java:112)
>        at
>
> org.apache.openjpa.kernel.ROPStoreManager.initialize(ROPStoreManager.java:57)
>        at
> org.apache.openjpa.kernel.BrokerImpl.initialize(BrokerImpl.java:1005)
>        at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:963)
>        ... 35 more
>
>
> What can be wrong with this simple example? Did I miss something?
>
> Cheers,
> Tobias
>
> --
> View this message in context:
> http://openjpa.208410.n2.nabble.com/NPE-with-Fetch-Join-Query-tp6222526p6222526.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>