Uploaded image for project: 'Application Server 7'
  1. Application Server 7
  2. AS7-4710

PersistenceUnitSearch violates the JPA spec

    XMLWordPrintable

Details

    • Hide

      Create an EAR, containing e.g. 2 EJB modules, each defining a persistence unit. Within at least one of them must reside an EJB, which references EntityManager using @PersistenceContext without explicitly defined unitName attribute (or ejb-jar.xml persistence-unit-name element).

      Show
      Create an EAR, containing e.g. 2 EJB modules, each defining a persistence unit. Within at least one of them must reside an EJB, which references EntityManager using @PersistenceContext without explicitly defined unitName attribute (or ejb-jar.xml persistence-unit-name element).
    • Medium

    Description

      There is no ability to deploy EAR, which contains several EJB-JAR modules, when more then one of them defining a persistence unit and at least one of EJBs within module "expresses a dependency on a container-managed EntityManager and its associated persistence context" (e.g. using @PersistenceContext annotation) without specifying the unitName.

      Stacktrace during deployment process of such EAR:
      13:45:36,765 INFO [org.jboss.as.server.deployment] (MSC service thread 1-4) JBAS015876: Starting deployment of "persistence-scope-test-ear-ear.ear"
      13:45:36,793 INFO [org.jboss.as.server.deployment] (MSC service thread 1-3) JBAS015876: Starting deployment of "persistence-scope-test-ear-ejb2-0.0.1-SNAPSHOT.jar"
      13:45:36,794 INFO [org.jboss.as.server.deployment] (MSC service thread 1-3) JBAS015876: Starting deployment of "persistence-scope-test-ear-ejb-0.0.1-SNAPSHOT.jar"
      13:45:36,886 INFO [org.jboss.as.jpa] (MSC service thread 1-1) JBAS011401: Read persistence.xml for primary
      13:45:36,889 INFO [org.jboss.as.jpa] (MSC service thread 1-4) JBAS011401: Read persistence.xml for primary
      13:45:36,898 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-7) MSC00001: Failed to start service jboss.deployment.subunit."persistence-scope-test-ear-ear.ear"."persistence-scope-test-ear-ejb2-0.0.1-SNAPSHOT.jar".DEPENDENCIES: org.jboss.msc.service.StartException in service jboss.deployment.subunit."persistence-scope-test-ear-ear.ear"."persistence-scope-test-ear-ejb2-0.0.1-SNAPSHOT.jar".DEPENDENCIES: Failed to process phase DEPENDENCIES of subdeployment "persistence-scope-test-ear-ejb2-0.0.1-SNAPSHOT.jar" of deployment "persistence-scope-test-ear-ear.ear"
      at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:119) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
      at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
      at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
      at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [rt.jar:1.6.0_31]
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [rt.jar:1.6.0_31]
      at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_31]
      Caused by: java.lang.IllegalArgumentException: JBAS011470: Persistence unitName was not specified and there are 2 persistence unit definitions in application deployment "persistence-scope-test-ear-ear.ear". Either change the application to have only one persistence unit definition or specify the unitName for each reference to a persistence unit.
      at org.jboss.as.jpa.container.PersistenceUnitSearch.resolvePersistenceUnitSupplier(PersistenceUnitSearch.java:69)
      at org.jboss.as.jpa.processor.JPAAnnotationParseProcessor.getPersistenceUnit(JPAAnnotationParseProcessor.java:284)
      at org.jboss.as.jpa.processor.JPAAnnotationParseProcessor.getBindingSource(JPAAnnotationParseProcessor.java:220)
      at org.jboss.as.jpa.processor.JPAAnnotationParseProcessor.processField(JPAAnnotationParseProcessor.java:151)
      at org.jboss.as.jpa.processor.JPAAnnotationParseProcessor.processPersistenceAnnotations(JPAAnnotationParseProcessor.java:118)
      at org.jboss.as.jpa.processor.JPAAnnotationParseProcessor.deploy(JPAAnnotationParseProcessor.java:90)
      at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:113) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
      ... 5 more

      13:45:36,899 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-8) MSC00001: Failed to start service jboss.deployment.subunit."persistence-scope-test-ear-ear.ear"."persistence-scope-test-ear-ejb-0.0.1-SNAPSHOT.jar".DEPENDENCIES: org.jboss.msc.service.StartException in service jboss.deployment.subunit."persistence-scope-test-ear-ear.ear"."persistence-scope-test-ear-ejb-0.0.1-SNAPSHOT.jar".DEPENDENCIES: Failed to process phase DEPENDENCIES of subdeployment "persistence-scope-test-ear-ejb-0.0.1-SNAPSHOT.jar" of deployment "persistence-scope-test-ear-ear.ear"
      at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:119) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
      at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
      at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
      at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [rt.jar:1.6.0_31]
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [rt.jar:1.6.0_31]
      at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_31]
      Caused by: java.lang.IllegalArgumentException: JBAS011470: Persistence unitName was not specified and there are 2 persistence unit definitions in application deployment "persistence-scope-test-ear-ear.ear". Either change the application to have only one persistence unit definition or specify the unitName for each reference to a persistence unit.
      at org.jboss.as.jpa.container.PersistenceUnitSearch.resolvePersistenceUnitSupplier(PersistenceUnitSearch.java:69)
      at org.jboss.as.jpa.processor.JPAAnnotationParseProcessor.getPersistenceUnit(JPAAnnotationParseProcessor.java:284)
      at org.jboss.as.jpa.processor.JPAAnnotationParseProcessor.getBindingSource(JPAAnnotationParseProcessor.java:220)
      at org.jboss.as.jpa.processor.JPAAnnotationParseProcessor.processField(JPAAnnotationParseProcessor.java:151)
      at org.jboss.as.jpa.processor.JPAAnnotationParseProcessor.processPersistenceAnnotations(JPAAnnotationParseProcessor.java:118)
      at org.jboss.as.jpa.processor.JPAAnnotationParseProcessor.deploy(JPAAnnotationParseProcessor.java:90)
      at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:113) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
      ... 5 more

      Issue is related to the AS7-2275 (https://issues.jboss.org/browse/AS7-2275).

      JPA 2.0 specification (in paragraph "8.2.2 Persistence Unit Scope") states that:

      "When referencing a persistence unit using the unitName annotation element or persistence-
      unit-name deployment descriptor element, the visibility scope of the persistence unit is
      determined by its point of definition:

      • A persistence unit that is defined at the level of an EJB-JAR, WAR, or application client jar is
      scoped to that EJB-JAR, WAR, or application jar respectively and is visible to the components
      defined in that jar or war."

      Although it says "when referencing... using the unitName", when in this case "unitName" attribute is omitted, I believe this (taking into account persistence units defined in other modules) is still a bug, cause:
      1. The scope of a persistence unit is all the same implied by the spec, e.g. by sentences like this: "The persistence.xml file may be used to designate more than one persistence unit within the same scope. The persistence.xml file may be used to designate more than one persistence unit within the same scope."
      2. AFAIK, neither JPA 2.0 nor EJB 3.1 specification defines any persistence unit choosing algorithm in case of unitName omission despite this attribute is optional.

      Code responsible for generating an aforementioned exception resides in org.jboss.as.jpa.container.PersistenceUnitSearch:

      PersistenceUnitsInApplication persistenceUnitsInApplication = DeploymentUtils.getTopDeploymentUnit(deploymentUnit).getAttachment(PersistenceUnitsInApplication.PERSISTENCE_UNITS_IN_APPLICATION);

      if (persistenceUnitsInApplication.getCount() > 1) {

      // AS7-2275 no unitName and there is more than one persistence unit;

      throw MESSAGES.noPUnitNameSpecifiedAndMultiplePersistenceUnits(persistenceUnitsInApplication.getCount(),DeploymentUtils.getTopDeploymentUnit(deploymentUnit));

      }

      So, since a developer haven't defined any EAR-level persistence unit ant tries to inject EntityManager without using the unitName - all persistence unit defined in other EJB/WAR modules are taken into account and application is prevented from deploying because of "false ambiguity".

      Attachments

        Issue Links

          Activity

            People

              smarlow1@redhat.com Scott Marlow
              a.kiselyov Alexander Kiselyov (Inactive)
              Votes:
              1 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: