OpenJPA
  1. OpenJPA
  2. OPENJPA-147

<T> T OpenJPAEntityManager.createInstance(Class<T> cls) fails when T is interface

    Details

    • Type: New Feature New Feature
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.1.0
    • Component/s: jpa
    • Labels:
      None

      Description

      According to JavaDoc, OpenJPAEntityManager.createInstance() method
      public <T> T createInstance(Class<T> cls);
      behaves as follows:

      "Create a new instance of type <code>cls</code>. If <code>cls</code> is
      an interface or an abstract class whose abstract methods follow the
      JavaBeans convention, this method will create a concrete implementation
      according to the metadata that defines the class"

      The method fails when T is an interface. The failure may be due to incorrect user configuration, however, further
      information on this extension method is not available in OpenJPA documentation.

      Firstly, how to specify metadata for a interface that has bean-style methods?
      Possibilities are:
      a) Annotating the Java interface definition with @Entity
      b) Specifying in <class>org.acme.IPerson</class> in persistence.xml

      Either of the above fails. a) fails at parsing b) fails with "no metadata"

      There may be a correct but undocumented way of specifying a managed interface. If that is the case, then this JIRA report should be treated as a documentation bug.

      1. iface.trace.1.txt
        10 kB
        Pinaki Poddar
      2. iface.trace.2.txt
        8 kB
        Pinaki Poddar
      3. iface.trace.3.txt
        73 kB
        Pinaki Poddar
      4. iface.trace.4.txt
        10 kB
        Pinaki Poddar
      5. TestInterface.java
        0.7 kB
        Pinaki Poddar
      6. IPerson.java
        0.2 kB
        Pinaki Poddar

        Issue Links

          Activity

          Hide
          Craig L Russell added a comment -

          >Firstly, how to specify metadata for a interface that has bean-style methods?
          >Possibilities are:
          >a) Annotating the Java interface definition with @Entity
          >b) Specifying in <class>org.acme.IPerson</class> in persistence.xml

          >Either of the above fails. a) fails at parsing b) fails with "no metadata"

          With a), does the failure occur in OpenJPA code, or does the compiler complain? What is the stack trace?

          With b), did you provide metadata as a file, in addition to referring to the interface in persistence.xml?

          Show
          Craig L Russell added a comment - >Firstly, how to specify metadata for a interface that has bean-style methods? >Possibilities are: >a) Annotating the Java interface definition with @Entity >b) Specifying in <class>org.acme.IPerson</class> in persistence.xml >Either of the above fails. a) fails at parsing b) fails with "no metadata" With a), does the failure occur in OpenJPA code, or does the compiler complain? What is the stack trace? With b), did you provide metadata as a file, in addition to referring to the interface in persistence.xml?
          Hide
          Pinaki Poddar added a comment -

          I have attached four trial-and-error scenarios

          Condition (a) is Java interface is annotated with @Entity and condition (b) is <class>IPerson</class> specified in persistence.xml.

          Case 1 (iface.trace.1.txt) both (a) and (b) are true : NPE in AnnotationPersistenceMetaDataParser.parseCallbackMethods()
          Case 2: (iface.trace.2.txt) not (a) but (b) : Metadata not found
          Case 3:(iface.trace.3.txt) (a) but not (b) : NPE in AnnotationPersistenceMetaDataParser.parseCallbackMethods()

          Case 4: As I plug the NPE during parsing, and keep both (a) and (b) then the code proceeds further to fail within Enhancer.

          Show
          Pinaki Poddar added a comment - I have attached four trial-and-error scenarios Condition (a) is Java interface is annotated with @Entity and condition (b) is <class>IPerson</class> specified in persistence.xml. Case 1 (iface.trace.1.txt) both (a) and (b) are true : NPE in AnnotationPersistenceMetaDataParser.parseCallbackMethods() Case 2: (iface.trace.2.txt) not (a) but (b) : Metadata not found Case 3:(iface.trace.3.txt) (a) but not (b) : NPE in AnnotationPersistenceMetaDataParser.parseCallbackMethods() Case 4: As I plug the NPE during parsing, and keep both (a) and (b) then the code proceeds further to fail within Enhancer.
          Hide
          Craig L Russell added a comment -

          Could you please attach the java definition of test.IPerson and the contents of META-INF/orm.xml to this issue?

          Show
          Craig L Russell added a comment - Could you please attach the java definition of test.IPerson and the contents of META-INF/orm.xml to this issue?
          Hide
          Pinaki Poddar added a comment -

          The Java interface definition is attached. I did not use an orm.xml.

          Show
          Pinaki Poddar added a comment - The Java interface definition is attached. I did not use an orm.xml.
          Hide
          Patrick Linskey added a comment -

          The recent commit adds support for this feature, but currently requires that the developer annotate interfaces with @ManagedInterface to enable the feature. Is this appropriate? Any other ideas for configuration / interfaces?

          One problem with @ManagedInterface is that it isn't intuitive for abstract class support. Perhaps we should decide how we eventually want to support abstract classes and see if we can make our managed interface support take that into account.

          Show
          Patrick Linskey added a comment - The recent commit adds support for this feature, but currently requires that the developer annotate interfaces with @ManagedInterface to enable the feature. Is this appropriate? Any other ideas for configuration / interfaces? One problem with @ManagedInterface is that it isn't intuitive for abstract class support. Perhaps we should decide how we eventually want to support abstract classes and see if we can make our managed interface support take that into account.
          Hide
          Pinaki Poddar added a comment -

          Excellent!

          But something I am still missing once I changed to new @ManagedInterface

          Here is an Interface:
          ===================================================
          package jira147;

          import org.apache.openjpa.persistence.ManagedInterface;

          @ManagedInterface
          public interface IPerson

          { public String getName(); public void setName(String name); }

          =====================================================
          Here is a test methood

          public void testNewInstance()

          { EntityManager em = emf.createEntityManager(); OpenJPAEntityManager oem = (OpenJPAEntityManager)em; Object ipc = oem.createInstance(IPerson.class); oem.getTransaction().begin(); oem.persist(ipc); oem.getTransaction().commit(); }

          =====================================================
          Here is a persistence unit

          <persistence-unit name="test">
          <class>jira147.IPerson</class>
          <properties>
          <property name="openjpa.ConnectionDriverName" value="com.mysql.jdbc.Driver"/>
          <property name="openjpa.ConnectionURL" value="jdbc:mysql://localhost/openjpa"/>
          </properties>
          </persistence-unit>
          ====================================================
          Here is the console
          Using OpenJPA 420667:610924
          62 test INFO [main] openjpa.Runtime - Starting OpenJPA 1.1.0-SNAPSHOT
          =======================================================
          Here is the Stack Trace

          java.lang.IllegalArgumentException: No registered metadata for type "interface jira147.IPerson".
          at org.apache.openjpa.enhance.PCRegistry.getMeta(PCRegistry.java:255)
          at org.apache.openjpa.enhance.PCRegistry.newInstance(PCRegistry.java:111)
          at org.apache.openjpa.kernel.BrokerImpl.newInstance(BrokerImpl.java:4167)
          at org.apache.openjpa.kernel.DelegatingBroker.newInstance(DelegatingBroker.java:1358)
          at org.apache.openjpa.persistence.EntityManagerImpl.createInstance(EntityManagerImpl.java:1068)
          at jira147.TestInterface.testNewInstance(TestInterface.java:22)

          Show
          Pinaki Poddar added a comment - Excellent! But something I am still missing once I changed to new @ManagedInterface Here is an Interface: =================================================== package jira147; import org.apache.openjpa.persistence.ManagedInterface; @ManagedInterface public interface IPerson { public String getName(); public void setName(String name); } ===================================================== Here is a test methood public void testNewInstance() { EntityManager em = emf.createEntityManager(); OpenJPAEntityManager oem = (OpenJPAEntityManager)em; Object ipc = oem.createInstance(IPerson.class); oem.getTransaction().begin(); oem.persist(ipc); oem.getTransaction().commit(); } ===================================================== Here is a persistence unit <persistence-unit name="test"> <class>jira147.IPerson</class> <properties> <property name="openjpa.ConnectionDriverName" value="com.mysql.jdbc.Driver"/> <property name="openjpa.ConnectionURL" value="jdbc:mysql://localhost/openjpa"/> </properties> </persistence-unit> ==================================================== Here is the console Using OpenJPA 420667:610924 62 test INFO [main] openjpa.Runtime - Starting OpenJPA 1.1.0-SNAPSHOT ======================================================= Here is the Stack Trace java.lang.IllegalArgumentException: No registered metadata for type "interface jira147.IPerson". at org.apache.openjpa.enhance.PCRegistry.getMeta(PCRegistry.java:255) at org.apache.openjpa.enhance.PCRegistry.newInstance(PCRegistry.java:111) at org.apache.openjpa.kernel.BrokerImpl.newInstance(BrokerImpl.java:4167) at org.apache.openjpa.kernel.DelegatingBroker.newInstance(DelegatingBroker.java:1358) at org.apache.openjpa.persistence.EntityManagerImpl.createInstance(EntityManagerImpl.java:1068) at jira147.TestInterface.testNewInstance(TestInterface.java:22)
          Hide
          Patrick Linskey added a comment -

          You need to list the interface (IPerson) in the persistence unit.

          I assume (but have not tested) that existing auto-scanning techniques would also work.

          Show
          Patrick Linskey added a comment - You need to list the interface (IPerson) in the persistence unit. I assume (but have not tested) that existing auto-scanning techniques would also work.

            People

            • Assignee:
              Unassigned
              Reporter:
              Pinaki Poddar
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development