Java EE - 通过 Glassfish 资源将 EJB 连接到 Oracle 数据库

Java EE - Connect EJB to Oracle Database through Glassfish resource

我是 Java 的新手,尤其是 EE。我启动了一个 EE 项目,该项目应提供 REST API,它将处理远程 Oracle 数据库中的 2 个实体。我正在使用 NetBeans,因为它是在 Enterprise Java 中完成任何事情的唯一方法(如我现在所见)。

我做了什么:

  1. 我在 Glassfish (v4.1-13) 中创建了 JDBC 池。我可以成功 ping 池。然后我为池创建了 JDBC 资源。
  2. 我为我需要处理的两个实体生成了实体 classes。

<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. 我有一个无状态 EJB,它像这样调用实体管理器:

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

  1. 然后,有一个 REST 服务 class 应该列出数据库中的实体。

    @Path("food") public class 食物资源 {

    @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();
        ...
    }
    

    }

不幸的是,一旦我请求 getAll 操作(访问 localhost:8080/semestralka-war/wr/food/list),我得到这个异常:

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

这是异常屏幕的屏幕截图:

仔细检查持久性单元和 glassfish 服务器中的连接池名称。你也可以用实体更新你的问题。

我可以看到你从 rest 服务调用的 ejb 是错误的。您需要添加带有包路径的远程接口名称。

假设您的包路径是 com.rs.www 那么您的查找字符串应该是以下一个:

 service = (FoodServiceInterface) ic.lookup("java:global/semestralka/semestralka-ejb/FoodServiceBean!com.rs.www.FoodServiceInterface");

谢谢。

终于,我找到了解决办法。问题出在我的 FoodServiceBean 中。我试图在 EJB 构造函数中实例化外观,但 EntityManager 是在构造函数之后注入的。所以这是帮助我解决问题的 Bean 代码。

@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);
}

请注意,我更改了持久性单元的名称只是为了确保没有拼写错误。

感谢您的帮助。