OpenJPA
  1. OpenJPA
  2. OPENJPA-1141

NPE at org.apache.openjpa.jdbc.meta.MappingInfo.mergeJoinColumn(MappingInfo.java:1400)

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.2.0
    • Fix Version/s: 1.2.2, 1.3.0, 2.0.0-beta
    • Component/s: jdbc
    • Labels:
      None

      Description

      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

      1. ddl.sql
        0.3 kB
        Michael Vorburger
      2. OpenJPA-1.2.x-OJ1141_10226009.patch
        32 kB
        Jody Grassel
      3. OpenJPA-1.3.x_OJ1141.patch
        33 kB
        Jody Grassel
      4. openjpa-1141.zip
        8 kB
        Igor Sakovich
      5. OpenJPA-Trunk_OJ1141.patch
        32 kB
        Jody Grassel
      6. OpenJPA-Trunk_OJ1141-2.patch
        15 kB
        Martin Dirichs
      7. TestMappingProblem.zip
        7 kB
        Yann

        Issue Links

          Activity

          Hide
          Michael Dick added a comment -

          The entities contain comments indicating that they were generated. Did you use the OpenJPA ReverseMappingTool, or something else (ie Dali)?

          If you used the OpenJPAReverseMappingTool then would it be possible to see the table ddl that resulted in these entities? It looks like some annotations need to be added to complete the mappings.

          Show
          Michael Dick added a comment - The entities contain comments indicating that they were generated. Did you use the OpenJPA ReverseMappingTool, or something else (ie Dali)? If you used the OpenJPAReverseMappingTool then would it be possible to see the table ddl that resulted in these entities? It looks like some annotations need to be added to complete the mappings.
          Hide
          Martin Dirichs added a comment - - edited
          Show
          Martin Dirichs added a comment - - edited See http://n2.nabble.com/NPE-at-org.apache.openjpa.jdbc.meta.MappingInfo.mergeJoinColumn(MappingInfo.java%3A1400)-tt3120428.html#a3231887 for an explanation of the root cause of this error. It also affects 2.0.0-M2.
          Hide
          Martin Dirichs added a comment -

          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.

          Show
          Martin Dirichs added a comment - 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.
          Hide
          Michael Vorburger added a comment -

          Michael Dick, in response to your questions (as also via IBM PMR 44438 500 624) :

          Attached a ddl.sql which represents the three physical tables that PortfolioEntity, NotepadEntity & TypeEntity need to map to. This is a simplified subset of a more complex existing (non changeable) real-world target DDL schema. Note that the defect (NPE) occurs inside OpenJPA within jdbc.meta.MappingInfo BEFORE any SQL at all is actually executed - this DDL is FYI as requested, but the initially provided test case actually fails with NPE and demonstrates the problem WITHOUT any DB / DDL. See Martin Dirichs comments above.

          Regarding the comment in the .java that says "This file has been automatically generated, DO NOT MODIFY!", please ignore that - strictly speaking all those *Entity classes (not just Notepad) were generated from some kind of in-house meta description, but NOT by the OpenJPAReverseMapping tool, but by a proprietary code gen. tool. That should be irrelevant for the purposes of this discussion though, please just assume for this discussion that it was hand-written, i.e. the generator could be adapted by us if there is a solution in adding any annotations as you suggest - but which?

          Show
          Michael Vorburger added a comment - Michael Dick, in response to your questions (as also via IBM PMR 44438 500 624) : Attached a ddl.sql which represents the three physical tables that PortfolioEntity, NotepadEntity & TypeEntity need to map to. This is a simplified subset of a more complex existing (non changeable) real-world target DDL schema. Note that the defect (NPE) occurs inside OpenJPA within jdbc.meta.MappingInfo BEFORE any SQL at all is actually executed - this DDL is FYI as requested, but the initially provided test case actually fails with NPE and demonstrates the problem WITHOUT any DB / DDL. See Martin Dirichs comments above. Regarding the comment in the .java that says "This file has been automatically generated, DO NOT MODIFY!", please ignore that - strictly speaking all those *Entity classes (not just Notepad) were generated from some kind of in-house meta description, but NOT by the OpenJPAReverseMapping tool, but by a proprietary code gen. tool. That should be irrelevant for the purposes of this discussion though, please just assume for this discussion that it was hand-written, i.e. the generator could be adapted by us if there is a solution in adding any annotations as you suggest - but which?
          Hide
          Michael Dick added a comment -

          Hi Michael,

          I haven't taken a look at this issue since I made the earlier remarks, I'll take another look this morning and get back to you. Martin's comments above are intriguing though - at first glance I thought it was an incomplete mapping issue, but now I'm not sure.

          Thanks for the explanation of how the entities get generated, too by the way.

          Show
          Michael Dick added a comment - Hi Michael, I haven't taken a look at this issue since I made the earlier remarks, I'll take another look this morning and get back to you. Martin's comments above are intriguing though - at first glance I thought it was an incomplete mapping issue, but now I'm not sure. Thanks for the explanation of how the entities get generated, too by the way.
          Hide
          B.J. Reed added a comment -

          One thing I tried was playing around with the entities and persisting them before creating/running the query.

          Looks like persisting a TypeEntity (even one that's not used) seems to tweak the algorithm enough to get around the NullPointerException.

          I changed the doTest method to do the following:

          public void testIt () throws Exception

          { EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); TypeEntity te = new TypeEntity(); em.persist(te); Query query = em.createQuery("SELECT o from Portfolio o"); query.getResultList(); em.getTransaction().commit(); em.close(); }
          Show
          B.J. Reed added a comment - One thing I tried was playing around with the entities and persisting them before creating/running the query. Looks like persisting a TypeEntity (even one that's not used) seems to tweak the algorithm enough to get around the NullPointerException. I changed the doTest method to do the following: public void testIt () throws Exception { EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); TypeEntity te = new TypeEntity(); em.persist(te); Query query = em.createQuery("SELECT o from Portfolio o"); query.getResultList(); em.getTransaction().commit(); em.close(); }
          Hide
          Michael Dick added a comment -

          Spoke with B.J. offline and he agreed to look at the issue.

          Show
          Michael Dick added a comment - Spoke with B.J. offline and he agreed to look at the issue.
          Hide
          B.J. Reed added a comment -

          Can someone else take a look at this? I had only agreed originally to look at the work around and have not had much of a chance to try to actually fix the problem. By having it assigned to me, I'm afraid that someone more capable may be kept from looking into this.

          Show
          B.J. Reed added a comment - Can someone else take a look at this? I had only agreed originally to look at the work around and have not had much of a chance to try to actually fix the problem. By having it assigned to me, I'm afraid that someone more capable may be kept from looking into this.
          Hide
          Jody Grassel added a comment -

          Update based on suggestions from code review.

          Show
          Jody Grassel added a comment - Update based on suggestions from code review.
          Hide
          Jody Grassel added a comment -

          Updated version of the patch, dated 10 26 2009.

          Show
          Jody Grassel added a comment - Updated version of the patch, dated 10 26 2009.
          Hide
          Jody Grassel added a comment -

          OpenJPA-1141 patch for trunk

          Show
          Jody Grassel added a comment - OpenJPA-1141 patch for trunk
          Hide
          Jody Grassel added a comment -

          Patch for OpenJPA 1.3.x

          Show
          Jody Grassel added a comment - Patch for OpenJPA 1.3.x
          Hide
          Martin Dirichs added a comment -

          I have tested patch OpenJPA-Trunk_OJ1141.patch with my application. Unfortunately, the patch doesn't seem to eliminate the problem. There seemed to be no difference at all.

          Digging further into this issue, I could spot in the code why the patch did not solve the problem. The patch adds a line to the bottom of MetaDataRepository.processBuffer() to reorder entities for further processing. Method processBuffer() is a bit strange at first view:

          private List<ClassMetaData> processBuffer(ClassMetaData meta, InheritanceOrderedMetaDataList buffer, int mode) {
          // if we're already processing a metadata, just buffer this one; when
          // the initial metadata finishes processing, we traverse the buffer
          // and process all the others that were introduced during reentrant calls
          if (!buffer.add(meta) || buffer.size() != 1)
          return null;

          // continually pop a metadata and process it until we run out; note
          // that each processing call might place more metas in the buffer as
          // one class tries to access metadata for another; also note that the
          // buffer orders itself from least to most derived
          ClassMetaData buffered;
          List<ClassMetaData> processed = new ArrayList<ClassMetaData>(5);
          while (!buffer.isEmpty())

          { buffered = buffer.peek(); buffered.resolve(mode); processed.add(buffered); buffer.remove(buffered); }

          // this line is added by the patch
          processed = resolveFKInPKDependenciesOrdering(processed);

          return processed;
          }

          Thus, the iteration within processBuffer() is only executed if the supplied list of entity meta data solely contains one item, which is also supplied as first parameter to the method. This puzzle is solved, of course, by taking into account that the line "buffered.resolve(mode);" may lead to recursive calls to processBuffer(), thereby growing the list of meta data while iterating over it in the outermost call.

          Note that the patch only adds a line behind the while loop. However, exceptions similar to the one reported in this JIRA issue occur within the while loop, during the recursion. The patch may happen to eliminate the meta data resolution problem for the supplied test setup, it does not work for the general case.

          The root problem lies in the usage of an InheritanceOrderedMetaDataList as buffer. This kind of list makes sure that new meta data entries put into the list are always inserted behind any meta data entries of super classes. This is fine, but it is not enough. If entities use other entities for their primary key fields, this is a dependency not taken into account by the InheritanceOrderedMetaDataList. Instead, entities not inheriting from each other are simply ordered alphabetically when inserted into the list.

          This is the real flaw of using the InheritanceOrderedMetaDataList in this context. Since resolving the meta data of an entity is only guaranteed to work if both super classes and entites referred to in the primary key fields are already resolved beforehand, the usage of InheritanceOrderedMetaDataList is error prone.

          There exists another approach to remove this kind of meta data resolution problems: Use a simple ArrayList instead of InheritanceOrderedMetaDataList. In the process of resolving the meta data for an entity, the current code already takes into account all possible dependencies between entities. In short, ClassMetaData.resolveMeta() works as follows:

          • resolve super class of current entity, if applicable
          • resolve primary key field entities of current entity, if applicable
            Both of these actions lead to calls to MetaDataRepository.processBuffer() with the respective entity meta data before processBuffer() is finally called for the current entity. Thus, all entities the current entity is dependent on are put into the buffer before the current entity. A simple array list thus is sufficient to let all entities be processed in the correct order.

          I've attached a corresponding patch called OpenJPA-Trunk_OJ1141-2.patch which implements these considerations. Although this patch removes the special logic within MetaDataRepository introduced by the original patch, the test cases of the original patch continue to work flawlessly as does the test suite attached to this JIRA issue. What is more, this fix is also able to cope with the mapping of my application, which happens to have many instances of foreign key references in primary keys as well as sub/superclass dependencies.

          Show
          Martin Dirichs added a comment - I have tested patch OpenJPA-Trunk_OJ1141.patch with my application. Unfortunately, the patch doesn't seem to eliminate the problem. There seemed to be no difference at all. Digging further into this issue, I could spot in the code why the patch did not solve the problem. The patch adds a line to the bottom of MetaDataRepository.processBuffer() to reorder entities for further processing. Method processBuffer() is a bit strange at first view: private List<ClassMetaData> processBuffer(ClassMetaData meta, InheritanceOrderedMetaDataList buffer, int mode) { // if we're already processing a metadata, just buffer this one; when // the initial metadata finishes processing, we traverse the buffer // and process all the others that were introduced during reentrant calls if (!buffer.add(meta) || buffer.size() != 1) return null; // continually pop a metadata and process it until we run out; note // that each processing call might place more metas in the buffer as // one class tries to access metadata for another; also note that the // buffer orders itself from least to most derived ClassMetaData buffered; List<ClassMetaData> processed = new ArrayList<ClassMetaData>(5); while (!buffer.isEmpty()) { buffered = buffer.peek(); buffered.resolve(mode); processed.add(buffered); buffer.remove(buffered); } // this line is added by the patch processed = resolveFKInPKDependenciesOrdering(processed); return processed; } Thus, the iteration within processBuffer() is only executed if the supplied list of entity meta data solely contains one item, which is also supplied as first parameter to the method. This puzzle is solved, of course, by taking into account that the line "buffered.resolve(mode);" may lead to recursive calls to processBuffer(), thereby growing the list of meta data while iterating over it in the outermost call. Note that the patch only adds a line behind the while loop. However, exceptions similar to the one reported in this JIRA issue occur within the while loop, during the recursion. The patch may happen to eliminate the meta data resolution problem for the supplied test setup, it does not work for the general case. The root problem lies in the usage of an InheritanceOrderedMetaDataList as buffer. This kind of list makes sure that new meta data entries put into the list are always inserted behind any meta data entries of super classes. This is fine, but it is not enough. If entities use other entities for their primary key fields, this is a dependency not taken into account by the InheritanceOrderedMetaDataList. Instead, entities not inheriting from each other are simply ordered alphabetically when inserted into the list. This is the real flaw of using the InheritanceOrderedMetaDataList in this context. Since resolving the meta data of an entity is only guaranteed to work if both super classes and entites referred to in the primary key fields are already resolved beforehand, the usage of InheritanceOrderedMetaDataList is error prone. There exists another approach to remove this kind of meta data resolution problems: Use a simple ArrayList instead of InheritanceOrderedMetaDataList. In the process of resolving the meta data for an entity, the current code already takes into account all possible dependencies between entities. In short, ClassMetaData.resolveMeta() works as follows: resolve super class of current entity, if applicable resolve primary key field entities of current entity, if applicable Both of these actions lead to calls to MetaDataRepository.processBuffer() with the respective entity meta data before processBuffer() is finally called for the current entity. Thus, all entities the current entity is dependent on are put into the buffer before the current entity. A simple array list thus is sufficient to let all entities be processed in the correct order. I've attached a corresponding patch called OpenJPA-Trunk_OJ1141-2.patch which implements these considerations. Although this patch removes the special logic within MetaDataRepository introduced by the original patch, the test cases of the original patch continue to work flawlessly as does the test suite attached to this JIRA issue. What is more, this fix is also able to cope with the mapping of my application, which happens to have many instances of foreign key references in primary keys as well as sub/superclass dependencies.
          Hide
          Igor Sakovich added a comment -

          I'm encountered simular NullPointerException at org.apache.openjpa.jdbc.meta.MappingInfo.mergeJoinColumn(MappingInfo.java:1415), when trying to use Entities as part of Primary Key in 1.2.2. There is no such problem in 2.0.0 and 2.0.1.
          I've prepare minimal set of Entities that reproduces this error.
          If I remove @JoinColumns from LineItem.order or remove Item.items — problem goes away. If I rename Product to Customer (with corresponding changes in other classes) — problem goes away too.

          <openjpa-1.2.2-r422266:898935 nonfatal general error> org.apache.openjpa.persistence.PersistenceException: null
          at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:196)
          at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:142)
          at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:192)
          at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:145)
          at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:56)
          at org.apache.openjpa.test.TestMapping.testMapping(TestMapping.java:11)
          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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
          at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
          at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
          at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
          at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
          at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
          at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
          at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
          at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
          at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
          at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
          at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
          at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
          at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)
          at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:115)
          at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:102)
          at org.apache.maven.surefire.Surefire.run(Surefire.java:180)
          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:350)
          at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)
          Caused by: java.lang.NullPointerException
          at org.apache.openjpa.jdbc.meta.MappingInfo.mergeJoinColumn(MappingInfo.java:1415)
          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:871)
          at org.apache.openjpa.jdbc.meta.MappingRepository.prepareMapping(MappingRepository.java:418)
          at org.apache.openjpa.meta.MetaDataRepository.preMapping(MetaDataRepository.java:757)
          at org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:644)
          at org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:393)
          at org.apache.openjpa.meta.MetaDataRepository.getMetaDataLocking(MetaDataRepository.java:366)
          at org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:360)
          at org.apache.openjpa.enhance.PCEnhancer.<init>(PCEnhancer.java:253)
          at org.apache.openjpa.enhance.PCEnhancer.<init>(PCEnhancer.java:224)
          at org.apache.openjpa.enhance.PCEnhancer.<init>(PCEnhancer.java:192)
          at org.apache.openjpa.enhance.ManagedClassSubclasser.prepareUnenhancedClasses(ManagedClassSubclasser.java:121)
          at org.apache.openjpa.kernel.AbstractBrokerFactory.loadPersistentTypes(AbstractBrokerFactory.java:310)
          at org.apache.openjpa.kernel.AbstractBrokerFactory.initializeBroker(AbstractBrokerFactory.java:228)
          at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:190)
          ... 32 more

          Show
          Igor Sakovich added a comment - I'm encountered simular NullPointerException at org.apache.openjpa.jdbc.meta.MappingInfo.mergeJoinColumn(MappingInfo.java:1415), when trying to use Entities as part of Primary Key in 1.2.2. There is no such problem in 2.0.0 and 2.0.1. I've prepare minimal set of Entities that reproduces this error. If I remove @JoinColumns from LineItem.order or remove Item.items — problem goes away. If I rename Product to Customer (with corresponding changes in other classes) — problem goes away too. <openjpa-1.2.2-r422266:898935 nonfatal general error> org.apache.openjpa.persistence.PersistenceException: null at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:196) at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:142) at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:192) at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:145) at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:56) at org.apache.openjpa.test.TestMapping.testMapping(TestMapping.java:11) 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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59) at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:115) at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:102) at org.apache.maven.surefire.Surefire.run(Surefire.java:180) 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:350) at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021) Caused by: java.lang.NullPointerException at org.apache.openjpa.jdbc.meta.MappingInfo.mergeJoinColumn(MappingInfo.java:1415) 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:871) at org.apache.openjpa.jdbc.meta.MappingRepository.prepareMapping(MappingRepository.java:418) at org.apache.openjpa.meta.MetaDataRepository.preMapping(MetaDataRepository.java:757) at org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:644) at org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:393) at org.apache.openjpa.meta.MetaDataRepository.getMetaDataLocking(MetaDataRepository.java:366) at org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:360) at org.apache.openjpa.enhance.PCEnhancer.<init>(PCEnhancer.java:253) at org.apache.openjpa.enhance.PCEnhancer.<init>(PCEnhancer.java:224) at org.apache.openjpa.enhance.PCEnhancer.<init>(PCEnhancer.java:192) at org.apache.openjpa.enhance.ManagedClassSubclasser.prepareUnenhancedClasses(ManagedClassSubclasser.java:121) at org.apache.openjpa.kernel.AbstractBrokerFactory.loadPersistentTypes(AbstractBrokerFactory.java:310) at org.apache.openjpa.kernel.AbstractBrokerFactory.initializeBroker(AbstractBrokerFactory.java:228) at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:190) ... 32 more

            People

            • Assignee:
              Jody Grassel
              Reporter:
              Yann
            • Votes:
              1 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development