I'm trying to create a jUnit test for my EJB's and if my app just contains a few beans everything's all good but as soon as I incorporate JPA and entity-classes my jUnit test blows up. My test fails at

ejbContainer = javax.ejb.embeddable.EJBContainer.createEJBContainer();

and the stack trace says the following:

apr 03, 2012 6:28:05 FM org.glassfish.deployment.admin.DeployCommand execute
SEVERE: Exception while preparing the app : Invalid resource : robbandsresor__pm
com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Invalid resource : robbandsresor__pm

I'm using NetBeans 7.1 and GlassFish 3.1.x (and jUnit 4) and this is a simple web application, and my Persistency Unit was created by NetBeans wizard and connects to a MS SQL 2008 Server I've installed locally on my computer. I can succesfully deploy/run my web app, I can sucesfully connect to my SQL Server and invoke NamedQueryns using the JPA Entity.

My persistence.xml 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="robbansfotbollsresorPU" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>robbandsresor</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties/>
</persistence-unit>
</persistence>

My glassfish-resources.xml looks like this

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "">
<resources>

        <jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="com.microsoft.sqlserver.jdbc.SQLServerDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="microsoft_sql_Book_saPool" non-transactional-connections="false" pool-resize-quantity="2" res-type="javax.sql.DataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">

    <property name="serverName" value="MAX-PC"/>
    <property name="databaseName" value="Book"/>
    <property name="User" value="sa"/>
    <property name="Password" value="server"/>
    <property name="URL" value="jdbc:sqlserver://MAX-PC\sqlserver;databaseName=Book"/>
    <property name="driverClass" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>

</jdbc-connection-pool>
<jdbc-resource enabled="true" jndi-name="robbandsresor" object-type="user" pool-name="microsoft_sql_Book_saPool"/>
</resources>

My test-class looks like this

package beans;

import java.util.Collection;
import javax.ejb.embeddable.EJBContainer;
import models.Customer;
import models.Game;
import models.Package;
import org.junit.*;
import static org.junit.Assert.*;

public class BookingBeanTest {

public BookingBeanTest() {
}

@BeforeClass
public static void setUpClass() throws Exception {
}

@AfterClass
public static void tearDownClass() throws Exception {
}

@Before
public void setUp() {
}

@After
public void tearDown() {
}

@Test
public void testSetAndGetBookingID() throws Exception {
    EJBContainer container = javax.ejb.embeddable.EJBContainer.createEJBContainer();
    BookingBean instance = (BookingBean)container.getContext().lookup("java:global/classes/BookingBean");
    Integer expResult = 123;
    Integer bookingID = 123;
    instance.setBookingID(bookingID);
    Integer result = instance.getBookingID();
    assertEquals(expResult, result);
    container.close();
}

}

And my EJB (Booking.java) looks like this
package beans;

import java.util.Collection;
import javax.ejb.Stateful;
import models.Customer;
import models.Game;
import models.Package;

@Stateful
public class BookingBean {

private Integer bookingID;
private Collection<models.Package> packageCollection;
private Game gameID;
private Customer custEmail;

public Integer getBookingID() {
    return bookingID;
}

public void setBookingID(Integer bookingID) {
    this.bookingID = bookingID;
}

public Customer getCustEmail() {
    return custEmail;
}

public void setCustEmail(Customer custEmail) {
    this.custEmail = custEmail;
}

public Game getGameID() {
    return gameID;
}

public void setGameID(Game gameID) {
    this.gameID = gameID;
}

public Collection<Package> getPackageCollection() {
    return packageCollection;
}

public void setPackageCollection(Collection<Package> packageCollection) {
    this.packageCollection = packageCollection;
}
}

With a corresponding Booking-entity

package models;
import valueobjects.*;
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

@Entity
@Table(name = "Booking")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Booking.findAll", query = "SELECT b FROM Booking b"),
@NamedQuery(name = "Booking.findByCustEmail", query = "SELECT b FROM Booking b WHERE b.custEmail = :custEmail"),
@NamedQuery(name = "Booking.findByBookingID", query = "SELECT b FROM Booking b WHERE b.bookingID = :bookingID")})
public class Booking implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@NotNull
@Column(name = "Booking_ID")
private Integer bookingID;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "bookingID")
private Collection<Package> packageCollection;
@JoinColumn(name = "Game_ID", referencedColumnName = "Game_ID")
@ManyToOne(optional = false)
private Game gameID;
@JoinColumn(name = "Cust_Email", referencedColumnName = "Cust_Email")
@ManyToOne(optional = false)
private Customer custEmail;

public Booking() {
}

public Booking(Integer bookingID) {
    this.bookingID = bookingID;
}

public Integer getBookingID() {
    return bookingID;
}

public void setBookingID(Integer bookingID) {
    this.bookingID = bookingID;
}

@XmlTransient
public Collection<Package> getPackageCollection() {
    return packageCollection;
}

public void setPackageCollection(Collection<Package> packageCollection) {
    this.packageCollection = packageCollection;
}

public Game getGameID() {
    return gameID;
}

public void setGameID(Game gameID) {
    this.gameID = gameID;
}

public Customer getCustEmail() {
    return custEmail;
}

public void setCustEmail(Customer custEmail) {
    this.custEmail = custEmail;
}

@Override
public int hashCode() {
    int hash = 0;
    hash += (bookingID != null ? bookingID.hashCode() : 0);
    return hash;
}

@Override
public boolean equals(Object object) {
    // TODO: Warning - this method won't work in the case the id fields are not set
    if (!(object instanceof Booking)) {
        return false;
    }
    Booking other = (Booking) object;
    if ((this.bookingID == null && other.bookingID != null) || (this.bookingID != null && !this.bookingID.equals(other.bookingID))) {
        return false;
    }
    return true;
}

@Override
public String toString() {
    return "models.Booking[ bookingID=" + bookingID + " ]";
}

public BookingVO getBookingVO() {
    return new BookingVO(bookingID, custEmail, gameID, packageCollection);
}

}

Hopefully someone can help me sort this out as I've been at this for some time now!

Dani AI

Generated

Short summary: the embedded EJB container is trying to deploy your persistence unit but cannot find the server-managed JTA DataSource it expects, so the persistence bootstrap fails with an "Invalid resource : <your-jndi-name>__pm" error. The persistence provider (GlassFish/EclipseLink) will try to resolve a PM/JTA resource and the embeddable instance does not automatically see the same jdbc resources that your NetBeans/installed domain provides. (download.oracle.com)

Practical options (pick one that fits your test scope):

  • Fast unit tests: keep tests out of container-managed JTA. Use a test-only persistence.xml (in src/test/resources) that uses RESOURCE_LOCAL and an in-memory DB (H2/Derby) so you can create an EntityManagerFactory locally and run tests without JNDI. This is the simplest and most portable approach for jUnit-level tests. (stackoverflow.com)
  • Integration tests that must use your real JTA DataSource: start the embedded GlassFish against a configuration that contains your jdbc resource (point createEJBContainer at a domain.xml that defines the pool/resource) or run tests on a real server via Arquillian. The embeddable API supports passing a configuration file/instance root so the embedded instance will see the resource definitions. (docs.oracle.com)

If you do go the embedded-domain route, a minimal example is to pass properties into createEJBContainer so it uses a domain.xml that already defines your jdbc pool/resource:

Map<String,Object> props = new HashMap<>();
props.put("org.glassfish.ejb.embedded.glassfish.configuration.file", "/path/to/domain.xml");
EJBContainer container = EJBContainer.createEJBContainer(props);

(GlassFish versions/behavior vary; some users report needing to set instance/installation properties as well.) (docs.oracle.com)

Quick debugging checklist: confirm the exact JNDI name your PU expects (GlassFish commonly exposes jdbc/ names), ensure the JDBC driver is visible to the embedded instance, check the embedded server logs for resource-listing, and consider a test-only PU (or Arquillian) if you want repeatable CI-friendly tests. — your short-term workaround (avoiding the JTA lookup and creating the EMF locally) is pragmatic for unit tests; for full integration testing pick one of the embedded-domain or Arquillian approaches above. (stackoverflow.com)

For future reference; it would seem as if it was this line that caused my trouble

<jta-data-source>robbandsresor</jta-data-source>

This however caused my servlet to crash on this line

@PersistenceUnit EntityManagerFactory emf;

Which in turn was solved by declaring the annotation as a local variable instead and initializing it using my Persistance Unit.

EntityManagerFactory emf = Persistence.createEntityManagerFactory("robbansfotbollsresorPU");
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.