Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fixing "Could not resolve a persistence unit..." errors when PU is specified, found

I'm running Glassfish 3.1-SNAPSHOT as of today (2010-11-12).

I'm using the embedded EJBContainer.

On the classpath, as reported by the EJBContainer, I have a META-INF/persistence.xml. This file defines two persistence units: one called "ngp" and one called "cx".

Debugging output shows that the Glassfish JPA deployer finds it, and recognizes both the cx PU and the ngp PU.

The EJBContainer bombs out with the following all-too-common JPA error:

java.lang.RuntimeException: Could not resolve a persistence unit corresponding to the persistence-context-ref-name [cx] in the scope of the module called [/Users/ljnelson/Projects/foo/target/test-classes/]. Please verify your application.
at com.sun.enterprise.deployment.BundleDescriptor.findReferencedPUViaEMRef(BundleDescriptor.java:693)
at com.sun.enterprise.deployment.EjbBundleDescriptor.findReferencedPUs(EjbBundleDescriptor.java:910)
at org.glassfish.persistence.jpa.JPADeployer.prepare(JPADeployer.java:140)
at com.sun.enterprise.v3.server.ApplicationLifecycle.prepareModule(ApplicationLifecycle.java:869)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:410)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
at org.glassfish.kernel.embedded.EmbeddedDeployerImpl.deploy(EmbeddedDeployerImpl.java:193)
at org.glassfish.kernel.embedded.EmbeddedDeployerImpl.deploy(EmbeddedDeployerImpl.java:142)
at org.glassfish.ejb.embedded.EJBContainerImpl.deploy(EJBContainerImpl.java:135)
at org.glassfish.ejb.embedded.EJBContainerProviderImpl.createEJBContainer(EJBContainerProviderImpl.java:132)
at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:127)

I stress again that the deployment logs show that at least the deployer encounters both persistence units.

The class that wants to use the "cx" PU contains the usual boilerplate:

@PersistenceContext(unitName="cx")
private EntityManager em;

The persistence.xml is present in (the usual Maven place) target/test-classes/META-INF and looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

    <persistence-unit name="cx" transaction-type="JTA">
        <jta-data-source>java:global/jdbc/H2Test</jta-data-source>
        <!-- snip -->
    </persistence-unit>

    <persistence-unit name="ngp" transaction-type="JTA">
        <jta-data-source>java:global/jdbc/H2Test</jta-data-source>
        <!-- snip -->
    </persistence-unit>

</persistence>

The Glassfish embedded EJBContainer, while doing its work, outputs this:

Nov 12, 2010 1:24:05 PM com.sun.logging.LogDomains$1 log
FINE: Got com.sun.enterprise.deployment.node.PersistenceUnitNode@2026c088
Nov 12, 2010 1:24:05 PM com.sun.logging.LogDomains$1 log
FINER: With attribute name
Nov 12, 2010 1:24:05 PM com.sun.logging.LogDomains$1 log
FINER: With value cx
Nov 12, 2010 1:24:05 PM com.sun.logging.LogDomains$1 log
FINE: in class com.sun.enterprise.deployment.PersistenceUnitDescriptor  method  setName with  cx
...snip...
Nov 12, 2010 1:24:05 PM com.sun.logging.LogDomains$1 log
FINE: Got com.sun.enterprise.deployment.node.PersistenceUnitNode@1648ff68
Nov 12, 2010 1:24:05 PM com.sun.logging.LogDomains$1 log
FINER: With attribute name
Nov 12, 2010 1:24:05 PM com.sun.logging.LogDomains$1 log
FINER: With value ngp
Nov 12, 2010 1:24:05 PM com.sun.logging.LogDomains$1 log
FINE: in class com.sun.enterprise.deployment.PersistenceUnitDescriptor  method  setName with  ngp

Troubleshooting recipes, anyone?

like image 680
Laird Nelson Avatar asked Nov 12 '10 17:11

Laird Nelson


2 Answers

This one is a combination of weird behavior and pilot error.

First, the pilot error.

The particular JUnit test case I was looking at was that of a colleague, and it was named as though it were an EJB itself, following our internal naming convention. This is probably a cut and paste error on my colleague's part.

I mention that because every time I opened the file I stared at it as though it itself were an EJB.

But of course it is not an EJB.

However, mysteriously, there is a @PersistenceContext annotation in there, and an EntityManager, which is unused. The persistence context has an attribute of--you guessed it--unitName="cx".

So the strange behavior is that somewhere in between the old EJB container, which ran this test case fine, and now, the EJB container began treating this non-EJB, non-special class as a valid target for @PersistenceContext injection. Perhaps this test case is being treated as a managed bean, but I was under the impression that managed beans in a non-CDI environment had to be annotated as such.

Anyhow, once I removed this spurious @PersistenceContext annotation, everything worked fine.

like image 145
Laird Nelson Avatar answered Oct 29 '22 15:10

Laird Nelson


If by mistake you put @PersistenceContext(name="cx") instead of @PersistenceContext(unitName="cx") you get the same error with everything else working.

like image 33
Tudor Avatar answered Oct 29 '22 14:10

Tudor