Search code examples
javaoracle-databasejpaglassfishejb

Java EE - Connect EJB to Oracle Database through Glassfish resource


I am total newbie in Java and EE especially. I started an EE project that should provide REST API which will handle 2 entities in remote Oracle Database. I am using NetBeans because it is the only way how to accomplish anything in Enterprise Java (as I see it now).

What I've done:

  1. I created JDBC pool in Glassfish (v4.1-13). I can ping the pool successfully. Then I created JDBC Resource for the pool.
  2. I generated Entity classes for the two entities I need to handle.

<persistence version="2.1" xmlns...>
  <persistence-unit name="semestralka-ejbPU" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/dbs</jta-data-source>
    <class>cz.ctu.bitjv.kopecj24.semestralka.entities.Food</class>
    <class>cz.ctu.bitjv.kopecj24.semestralka.entities.User</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="eclipselink.target-database" value="Oracle"/>
    </properties>
  </persistence-unit>
</persistence>

  1. I have a stateless EJB which calls entity manager like this:

public FoodServiceBean()
{
  this.facade = new FoodFacade(Food.class);
  this.facade.setEntityManager(Persistence.createEntityManagerFactory("semestralka-ejbPU").createEntityManager());
}

  1. Then, there is a REST service class that should list the entities from the database.

    @Path("food") public class FoodResource {

    @Context
    private UriInfo context;
    
    private FoodServiceInterface service;
    
    /**
     * Creates a new instance of FoodResource
     */
    public FoodResource() {
        try {
            InitialContext ic = new InitialContext();
            service = (FoodServiceInterface) ic.lookup("java:global/semestralka/semestralka-ejb/FoodServiceBean");
        } catch (NamingException ex) {...} 
    }
    
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("list")
    public String getAll() {
        List<Food> foods = service.listAllFood();
        ...
    }
    

    }

Unfortunately, once I request the getAll action (visit localhost:8080/semestralka-war/wr/food/list ) I get this exception:

Warning:   StandardWrapperValve[cz.ctu.bitjv.kopecj24.semestralka.rest.ApplicationConfig]: Servlet.service() for servlet cz.ctu.bitjv.kopecj24.semestralka.rest.ApplicationConfig threw exception
javax.naming.NameNotFoundException: dbs not found

Here is a screenshot of the exception screen: Glassfish 500 Error screen


Solution

  • Finally, I've found a solution. Problem was in my FoodServiceBean. I was trying to instantiate the facade in the EJB constructor but the EntityManager is injected after the constructor. So here is code of the Bean that helped me solve the issue.

    @Stateless
    @EJB(beanInterface=FoodServiceInterface.class, name="FoodServiceBean")
    public class FoodServiceBean implements FoodServiceInterface {    
    
    @PersistenceContext(unitName="testPU")
    private EntityManager em;
    
    private FoodFacade facade;
    
    public FoodServiceBean()
    {
    
    }
    
    @PostConstruct
    public void init() {
        this.facade = new FoodFacade(Food.class);
        this.facade.setEntityManager(em);
    }
    

    Please note that I changed the name of persistence unit just to be sure there are no typos.

    Thanks for the help.