Hello Yann,
this seems to be a flaw in the OpenJPA mapping source indeed. I
just got the same error here with the 2.0.0-M2 version (its line
1473 in org.apache.openjpa.jdbc.meta.MappingInfo.java there).
The error occurred after introducing a trivial change in the domain
model.
Looking at the sources, I could track the root of the problem to
file org.apache.openjpa.jdbc.meta.ClassMapping, method
resolveNonRelationalMapping(). Here it says:
void resolveNonRelationMappings() {
// make sure primary key fields are resolved first because other
// fields might rely on them
FieldMapping[] fms = getPrimaryKeyFieldMappings();
for (int i = 0; i < fms.length; i++)
fms[i].resolve(MODE_MAPPING);
// resolve defined fields that are safe; that don't rely on other
types
// also being resolved. don't use getDefinedFields b/c it relies on
// whether fields are mapped, which isn't known yet
fms = getFieldMappings();
for (int i = 0; i < fms.length; i++)
if (fms[i].getDefiningMetaData() == this
&& !fms[i].isTypePC() && !fms[i].getKey().isTypePC()
&& !fms[i].getElement().isTypePC())
fms[i].resolve(MODE_MAPPING);
[...]
}
This code is run as part of establishing the mapping information
for all persistent classes. The code assumes to deal only with
non-relational fields, as the method name already suggests.
In the second half of the code, in the handling of non-primary-key
fields, this assumption is correctly checked as to whether it holds for
each field to resolve. However, in the first part of the code, all
primary key fields are tried to be resolved regardless of their being
simple types or not.
In your case, with primary key fields consisting
of references to other persistent types, this code leads to the
errors described by you - unless you're lucky and by chance
the order in which classes are resolved happens to match
their references among each other. This is the reason I got
away without problems until I introduced some unrelated change
that changed the order of class resolution.
There may be more than one approach to fixing this. Since my
understanding of the mapping code is hopelessly incomplete, I
don't dare to suggest any patches. However, trying to implement
an ordering based on the references of primary key fields to
other persistent entities solved my problem and assured me
that the above is a valid analysis of this error. Someone more
knowledgable could now step in and implement a solution for
http://issues.apache.org/jira/browse/OPENJPA-1141
based on these insights into the error cause.
Kind regards,
Martin Dirichs.
Yann Andenmatten wrote:
>
> Hello!
>
> We have the NPE shown below in a reproducible testcase (ZIP attached to
> this JIRA issue: https://issues.apache.org/jira/browse/OPENJPA-1141
> <https://issues.apache.org/jira/browse/OPENJPA-1141> ).
>
> We've reduced our complex intended target domain model (about 200+
> Entities) to a simpler model with only 3 classes which illustrate the
> problem: You'll find attached a test project with a first entity which
> has a a OneToMany (with an ElementJoinColumns, but that shouldn't
> matter?) to a second entity has a ManyToOne to a third entity. The
> middle entity has a Composite ID Class including a ManyToOne as a key,
> which according to
> http://openjpa.apache.org/builds/1.2.0/apache-openjpa-1.2.0/docs/manual/
> ref_guide_pc_oid.html#ref_guide_pc_oid_entitypk is supported, so this
> seems a bug in OpenJPA's mapping algos, somehow?
>
>
> Appreciate any ideas what we may be doing wrong, or bugfixes if this is
> indeed an OpenJPA Defect, as we suspect.
>
> Regards,
> Michael & Yann
>
> <openjpa-1.2.1-r752877:753278 nonfatal general error>
> org.apache.openjpa.persistence.PersistenceException: null
> at
> org.apache.openjpa.kernel.QueryImpl.compileForCompilation(QueryImpl.java
> :610)
> at
> org.apache.openjpa.kernel.QueryImpl.compileForExecutor(QueryImpl.java:66
> 7)
> at
> org.apache.openjpa.kernel.QueryImpl.getOperation(QueryImpl.java:1492)
> at
> org.apache.openjpa.kernel.DelegatingQuery.getOperation(DelegatingQuery.j
> ava:123)
> at
> org.apache.openjpa.persistence.QueryImpl.execute(QueryImpl.java:243)
> at
> org.apache.openjpa.persistence.QueryImpl.getResultList(QueryImpl.java:29
> 4)
> at
> testcase.TestMappingProblem.doTest(TestMappingProblem.java:42)
> at
> testcase.TestMappingProblem.testIt(TestMappingProblem.java:20)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.jav
> a:39)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessor
> Impl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at junit.framework.TestCase.runTest(TestCase.java:154)
> at junit.framework.TestCase.runBare(TestCase.java:127)
> at junit.framework.TestResult$1.protect(TestResult.java:106)
> at junit.framework.TestResult.runProtected(TestResult.java:124)
> at junit.framework.TestResult.run(TestResult.java:109)
> at junit.framework.TestCase.run(TestCase.java:118)
> at junit.framework.TestSuite.runTest(TestSuite.java:208)
> at junit.framework.TestSuite.run(TestSuite.java:203)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.jav
> a:39)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessor
> Impl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at
> org.apache.maven.surefire.junit.JUnitTestSet.execute(JUnitTestSet.java:2
> 13)
> at
> org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSe
> t(AbstractDirectoryTestSuite.java:140)
> at
> org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(Abstr
> actDirectoryTestSuite.java:127)
> at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.jav
> a:39)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessor
> Impl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at
> org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(Suref
> ireBooter.java:345)
> at
> org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java
> :1009)
> Caused by: java.lang.NullPointerException
> at
> org.apache.openjpa.jdbc.meta.MappingInfo.mergeJoinColumn(MappingInfo.jav
> a:1400)
> at
> org.apache.openjpa.jdbc.meta.MappingInfo.createJoins(MappingInfo.java:12
> 06)
> at
> org.apache.openjpa.jdbc.meta.MappingInfo.createForeignKey(MappingInfo.ja
> va:968)
> at
> org.apache.openjpa.jdbc.meta.ValueMappingInfo.getTypeJoin(ValueMappingIn
> fo.java:104)
> at
> org.apache.openjpa.jdbc.meta.strats.RelationFieldStrategy.map(RelationFi
> eldStrategy.java:157)
> at
> org.apache.openjpa.jdbc.meta.FieldMapping.setStrategy(FieldMapping.java:
> 121)
> at
> org.apache.openjpa.jdbc.meta.RuntimeStrategyInstaller.installStrategy(Ru
> ntimeStrategyInstaller.java:80)
> at
> org.apache.openjpa.jdbc.meta.FieldMapping.resolveMapping(FieldMapping.ja
> va:454)
> at
> org.apache.openjpa.jdbc.meta.FieldMapping.resolve(FieldMapping.java:419)
>
> at
> org.apache.openjpa.jdbc.meta.ClassMapping.resolveNonRelationMappings(Cla
> ssMapping.java:869)
> at
> org.apache.openjpa.jdbc.meta.MappingRepository.prepareMapping(MappingRep
> ository.java:339)
> at
> org.apache.openjpa.meta.MetaDataRepository.preMapping(MetaDataRepository
> .java:662)
> at
> org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.ja
> va:549)
> at
> org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepositor
> y.java:308)
> at
> org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepositor
> y.java:363)
> at
> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getClassMetaData(JP
> QLExpressionBuilder.java:159)
> at
> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.resolveClassMetaDat
> a(JPQLExpressionBuilder.java:139)
> at
> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getCandidateMetaDat
> a(JPQLExpressionBuilder.java:225)
> at
> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getCandidateMetaDat
> a(JPQLExpressionBuilder.java:195)
> at
> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getCandidateType(JP
> QLExpressionBuilder.java:188)
> at
> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.access$600(JPQLExpr
> essionBuilder.java:69)
> at
> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder$ParsedJPQL.populate
> (JPQLExpressionBuilder.java:1756)
> at
> org.apache.openjpa.kernel.jpql.JPQLParser.populate(JPQLParser.java:56)
> at
> org.apache.openjpa.kernel.ExpressionStoreQuery.populateFromCompilation(E
> xpressionStoreQuery.java:153)
> at
> org.apache.openjpa.kernel.QueryImpl.newCompilation(QueryImpl.java:658)
> at
> org.apache.openjpa.kernel.QueryImpl.compilationFromCache(QueryImpl.java:
> 639)
> at
> org.apache.openjpa.kernel.QueryImpl.compileForCompilation(QueryImpl.java
> :605)
> ... 33 more
>
> ____________________________________________________________
>
> This email and any files transmitted with it are CONFIDENTIAL and
> intended
> solely for the use of the individual or entity to which they are
> addressed.
> Any unauthorized copying, disclosure, or distribution of the material
> within
> this email is strictly forbidden.
> Any views or opinions presented within this e-mail are solely those of
> the
> author and do not necessarily represent those of Odyssey Financial
> Technologies SA unless otherwise specifically stated.
> An electronic message is not binding on its sender. Any message
> referring to
> a binding engagement must be confirmed in writing and duly signed.
> If you have received this email in error, please notify the sender
> immediately
> and delete the original.
>
--
View this message in context:
http://n2.nabble.com/NPE-at-org.apache.openjpa.jdbc.meta.MappingInfo.mergeJoinColumn%28MappingInfo.java%3A1400%29-tp3120428p3231887.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.