如何解决 Java EE EJB Glassfish 错误 javax.naming.NamingException: 调用异常: Got null ComponentInvocation?

How to solve Java EE EJB Glassfish error javax.naming.NamingException: Invocation exception: Got null ComponentInvocation?

我在使用 EJB 创建简单数据库时遇到问题。我使用 Maven 在 Netbeans 中创建了一个 Web 项目。我使用的是 Glassfish 5,但问题也发生在 glassfish 4 上。

这是我的类。

Ui_model.java:

@Named("model")
@Stateless
public class Ui_model implements Serializable{

    @Inject 
    PizzaRepository pizzas;

    public Ui_model() {
    }

    @PostConstruct
    public void init(){

        Pizza one = new Pizza(1, "Pizza Margaritta", 4.5);
        Pizza two = new Pizza(2, "Pizza Napoli", 5);
        Pizza three = new Pizza(3, "Pizza Calzone", 6);

        pizzas.createDB(one);
        pizzas.createDB(two);
        pizzas.createDB(three);  
    }
}

PizzaRepository.java:

@Named
@ApplicationScoped
public class PizzaRepository implements Serializable{
    @PersistenceContext(unitName="Unit")
    protected EntityManager em;

    public void createDB(Pizza pizza){
        try{
            em.persist(pizza);
        }catch(RollbackException e){
            System.out.println(e.getMessage());
        }

    }
}

Pizza.java:

@Entity
public class Pizza implements Serializable{
    @Id
    int number;
    String name;
    double price;

    public Pizza(int number, String name, double price) {
        this.number = number;
        this.name = name;
        this.price = price;
    }
    public Pizza(){

    }
}

这是我的 persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="Unit" transaction-type="JTA">
        <jta-data-source>java:app/jdbc/testdb</jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <!-- database connection -->
            <property name="javax.persistence.schema-generation.database.action" value="drop-and-create" />
        </properties>
    </persistence-unit>
</persistence>

这是我的玻璃鱼-resources.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<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="org.apache.derby.jdbc.ClientDataSource" 
                          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="derby_net_testdb_usernamePool" 
                          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="localhost"/>
        <property name="portNumber" value="1527"/>
        <property name="databaseName" value="testdb"/>
        <property name="User" value="username"/>
        <property name="Password" value="123456"/>
        <property name="URL" value="jdbc:derby://localhost:1527/testdb"/>
        <property name="driverClass" value="org.apache.derby.jdbc.ClientDriver"/>
    </jdbc-connection-pool>
    <jdbc-resource enabled="true" 
                   jndi-name="java:app/jdbc/testdb" 
                   object-type="user" 
                   pool-name="java:app/derby_net_testdb_usernamePool"/>
</resources>

我的项目结构:

当我 运行 出现以下错误时:

奇怪的是,这仍然会在 testdb 中创建一个名为 Pizza 的空 table,但没有任何条目。所以这并不意味着程序没有找到数据库本身。我真的不知道该怎么做。该项目最初要大得多,但我将其分解以解决基本问题,而且没有比这更容易的了。仍然不起作用。我将不胜感激有关如何修复它的任何建议。

编辑: asadmin list-jndi-entries 提示:

java:global: com.sun.enterprise.naming.impl.TransientContext
UserTransaction: com.sun.enterprise.transaction.startup.TransactionLifecycleService
__internal_java_app_for_app_client__testdb__java:app: com.sun.enterprise.naming.impl.TransientContext
concurrent: com.sun.enterprise.naming.impl.TransientContext
com.sun.enterprise.container.common.spi.util.InjectionManager: com.sun.enterprise.container.common.impl.util.InjectionManagerImpl
jms: com.sun.enterprise.naming.impl.TransientContext
ejb: com.sun.enterprise.naming.impl.TransientContext
jdbc: com.sun.enterprise.naming.impl.TransientContext
Command list-jndi-entries executed successfully.

asadmin list-jndi-entries --context jdbc 提示:

__default: org.glassfish.resourcebase.resources.api.ResourceProxy
__TimerPool: org.glassfish.resourcebase.resources.api.ResourceProxy
sample: org.glassfish.resourcebase.resources.api.ResourceProxy
Command list-jndi-entries executed successfully.

我认为问题在于 jdbc-resource pool-namejdbc-connection-pool name 不匹配。第一个有 java:app/ 前缀。尝试删除它。

请参阅此处的最小示例:https://github.com/payara/Payara-Examples/blob/master/payara-micro/database-ping/src/main/webapp/WEB-INF/glassfish-resources.xml

我可以通过将 glassfish.xml 放入 src 中的安装文件来解决问题。我也得到了一位朋友的帮助,他给了我他的文件。

glassfish.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
    <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="org.apache.derby.jdbc.ClientDataSource" 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="derby_net_testdb_pizzaPool" 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="localhost"/>
            <property name="portNumber" value="1527"/>
            <property name="databaseName" value="testdb"/>
            <property name="User" value="username"/>
            <property name="Password" value="123456"/>
            <property name="connectionAttributes" value=";create=true" />
            <property name="URL" value="jdbc:derby://localhost:1527/testdb;create=true"/>
            <property name="driverClass" value="org.apache.derby.jdbc.ClientDriver"/>
        </jdbc-connection-pool>
        <jdbc-resource enabled="true" jndi-name="jdbc/testdb" object-type="user" pool-name="derby_net_testdb_pizzaPool"/>
    </resources>

persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="Unit" transaction-type="JTA">
    <jta-data-source>jdbc/testdb</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <!--<property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/ModulDB"/>
        <property name="javax.persistence.jdbc.user" value="pizza"/>
        <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
        <property name="javax.persistence.jdbc.password" value="123456"/>-->
      <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
    </properties>
  </persistence-unit>
</persistence>

然而,由于持续调用,我收到了无法创建无状态 EJB 的错误消息。我可以通过不在 PostConstruct init() 中调用 createDB() 来解决这个问题。我不知道为什么,但它不适用于 post 构造。现在到目前为止一切正常。非常感谢大家。