[
https://issues.apache.org/jira/browse/OPENJPA-1141?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12733526#action_12733526
]
Martin Dirichs commented on OPENJPA-1141:
-----------------------------------------
There seems to be no problem with the mapping of the supplied testcase as such.
The reported exception is caused while OpenJPA resolves the primary key fields
of NotepadEntity. Since one of the primary key fields of NotepadEntity is the
id of another entity, namely TypeEntity, the primary key fields of
NotepadEntity may only be completely resolved after TypeEntity has been
resolved. However, the mapping data resolution algorithm of OpenJPA doesn't
take into account this type of dependency between entities.
See org.apache.openjpa.jdbc.meta.ClassMapping, methods
resolveNonRelationMappings() and resolveMapping(). Inside the latter, there
already seems to be a workaround for this deficiency of OpenJPAs resolution
strategy. Here is says in line 838 (I'm referencing to the 2.0.0-M2 source):
// set resolve mode to force this field mapping to be
// resolved again. The need to resolve again occurs when
// a primary key is a relation field with the foreign key
// annotation. In this situation, this primary key field
// mapping is resolved during the call to
// resolveNonRelationMapping. Since it is a relation
// field, the foreign key will be constructed. However,
// the primary key of the parent entity may not have been
// resolved yet, resulting in missing information in the fk
Unfortunately, there are situations such as in the reported test case that
cause an exception before the code following the above comment runs. A more
promising strategy would be to resolve the entities in the correct order taking
into account the dependencies of their primary key fields. Then this workaround
would not be needed at all and the reported exception would no longer happen.
Of course, the code responsible for determining the correct order of entity
resolution would have to deal with cycles, which may occur as the result of
incorrect mappings. However, I can't think of any situation where cyclic
references of primary key fields between entities would make any sense, so this
case can probably reported as an error and remain unhandled.
Oh, btw. I would be glad to help testing any fix for this.
> NPE at
> org.apache.openjpa.jdbc.meta.MappingInfo.mergeJoinColumn(MappingInfo.java:1400)
> ---------------------------------------------------------------------------------------
>
> Key: OPENJPA-1141
> URL: https://issues.apache.org/jira/browse/OPENJPA-1141
> Project: OpenJPA
> Issue Type: Bug
> Components: jdbc
> Affects Versions: 1.2.0
> Reporter: Yann
> Fix For: 1.2.2
>
> Attachments: TestMappingProblem.zip
>
>
> We have the NPE shown below in a reproducible testcase (ZIP attached to JIRA
> ...).
> 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?
> <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:667)
> at
> org.apache.openjpa.kernel.QueryImpl.getOperation(QueryImpl.java:1492)
> at
> org.apache.openjpa.kernel.DelegatingQuery.getOperation(DelegatingQuery.java:123)
> at
> org.apache.openjpa.persistence.QueryImpl.execute(QueryImpl.java:243)
> at
> org.apache.openjpa.persistence.QueryImpl.getResultList(QueryImpl.java:294)
> 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.java:39)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.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.java:39)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at
> org.apache.maven.surefire.junit.JUnitTestSet.execute(JUnitTestSet.java:213)
> at
> org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
> at
> org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.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.java:39)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at
> org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.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.java:1400)
> at
> org.apache.openjpa.jdbc.meta.MappingInfo.createJoins(MappingInfo.java:1206)
> at
> org.apache.openjpa.jdbc.meta.MappingInfo.createForeignKey(MappingInfo.java:968)
> at
> org.apache.openjpa.jdbc.meta.ValueMappingInfo.getTypeJoin(ValueMappingInfo.java:104)
> at
> org.apache.openjpa.jdbc.meta.strats.RelationFieldStrategy.map(RelationFieldStrategy.java:157)
> at
> org.apache.openjpa.jdbc.meta.FieldMapping.setStrategy(FieldMapping.java:121)
> at
> org.apache.openjpa.jdbc.meta.RuntimeStrategyInstaller.installStrategy(RuntimeStrategyInstaller.java:80)
> at
> org.apache.openjpa.jdbc.meta.FieldMapping.resolveMapping(FieldMapping.java:454)
> at
> org.apache.openjpa.jdbc.meta.FieldMapping.resolve(FieldMapping.java:419)
> at
> org.apache.openjpa.jdbc.meta.ClassMapping.resolveNonRelationMappings(ClassMapping.java:869)
> at
> org.apache.openjpa.jdbc.meta.MappingRepository.prepareMapping(MappingRepository.java:339)
> at
> org.apache.openjpa.meta.MetaDataRepository.preMapping(MetaDataRepository.java:662)
> at
> org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:549)
> at
> org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:308)
> at
> org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:363)
> at
> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getClassMetaData(JPQLExpressionBuilder.java:159)
> at
> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.resolveClassMetaData(JPQLExpressionBuilder.java:139)
> at
> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getCandidateMetaData(JPQLExpressionBuilder.java:225)
> at
> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getCandidateMetaData(JPQLExpressionBuilder.java:195)
> at
> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getCandidateType(JPQLExpressionBuilder.java:188)
> at
> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.access$600(JPQLExpressionBuilder.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(ExpressionStoreQuery.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 message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.