0

请帮忙,这让我发疯了。我已经研究了几个小时,找不到与我的情况相匹配的例子。

我正在编写一个非常简单的 Java EE 应用程序,它从独立客户端对用户进行身份验证。在 Netbeans 7.3 中,我有一个带有 EJB 模块的 Java EE 应用程序项目、一个应用程序客户端项目和一个用于 bean 远程接口和实体的单独的 java 类库。

EJB 模块有一个bean (AccountsBean.java),类库项目有bean 的远程接口(AccountsBeanRemote.java)、实体(Account.java) 和persistence.xml 文件。这是项目布局的图片,您可以清楚地看到它:http: //snag.gy/EoyQa.jpg

我想将 Account 实例传递给客户端。

我正在使用 Glassfish 3.1 和 Java DB (Derby)。

我有 3 个数据库:AccountsTest(我想在这里使用)、sample 和 sun-appserv-samples(这两个是在 Glassfish 安装期间创建的)。

问题是我在persistence.xml 中指定什么数据库连接并不重要,表总是在示例数据库sun-appserv-samples 中创建。在我看来,bean 忽略了 persistence.xml 文件。也许问题是persistence.xml 与bean 位于一个单独的项目中,但如果我想将Account 实例传递给远程客户端,这是IDE 允许我这样做的唯一方法。

这是我的persistence.xml:

<?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="LoginTest-libPU" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>logintest.lib.Account</class>
    <properties>
      <property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/AccountsTest"/>
      <property name="javax.persistence.jdbc.password" value="app"/>
      <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
      <property name="javax.persistence.jdbc.user" value="app"/>
      <property name="eclipselink.ddl-generation" value="create-tables"/>
    </properties>
  </persistence-unit>
</persistence>

和 AccountsBean.java:

@Stateless
public class AccountsBean implements AccountsBeanRemote {

    @PersistenceContext(unitName = "LoginTest-libPU")
    EntityManager em;

    @Override
    public Account create(String name, String password) {
        ...
    }

    @Override
    public void remove(int id) {
        ...
    }

    @Override
    public boolean checkPassword(int id, String password) {
        ...
    }
}

帐户.java:

@Entity
@Table(name = "ACCOUNTS")
public class Account implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private String password;

    public Account() {
    }

    ...other methods

我想我没有正确配置EntityManager,但是我应该把persistence.xml放在哪里?如果我把它放在 EJB 模块中,我也必须把实体放在 EJB 模块中,客户端将无法访问它们。

提前致谢!

4

1 回答 1

0

首先让我说明一下,我不清楚您为什么会看到这种行为,因为鉴于您在 Glassfish/Java EE 运行时中所做的事情,我不熟悉预期的行为:您正在设置直接联系。相反,在 Java EE 环境中,您需要“容器管理的持久性单元”[这里有一个猜测:容器默认 jta-data-source 为 'sun-appserv-samples']。

因此,让 Java EE 为您管理连接:

  1. 在 Glassfish 中,定义一个 ID 为“TestAccountPool”的 JDBC 连接池。您可以从管理面板或通过命令行执行此操作。这指定了您的数据源类名(在此处查找 Derby)、事务隔离级别和配置属性,例如:

    networkProtocol=jdbc\\:derby
    serverName=localhost
    port=1527  [OR portNumber=1527; I use port, some docs say portNumber]
    databaseName=AccountsTest
    user=app
    password=app
    
  2. 使用 JNDI 名称“jdbc/TestAccountData”定义一个引用“TestAccountPool”的 JDBC 资源。

  3. 调整您的persistence.xml文件以使用 JNDI 名称引用托管数据库连接:

    <?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="LoginTest-libPU" transaction-type="JTA">
    
        <jta-data-source>jdbc/TestAccountData</jta-data-source>
    
        <class>logintest.lib.Account</class>
    
        <properties>
          <property name="eclipselink.ddl-generation" value="create-tables"/>
        </properties>
      </persistence-unit>
    </persistence>
    

支持 Java SE 客户端

如果您还想在 Java SE 中使用您的实体,那么:

  1. 将您最初定义的内容添加<persistence-unit> ... </persistence-unit>persistence.xml文件中。

  2. 更改第二个持久性单元的名称;它必须是唯一的。我的工具(带有 glassfish 插件的 eclipse)抱怨多个持久性单元;我忽略了这样的警告。

  3. 将事务类型从“JTA”更改为“RESOURCE_LOCAL”,或者只是将其删除:在 Java EE 容器中,事务类型默认为 JTA(根据规范),在 Java SE 中默认为 RESOURCE_LOCAL

  4. 在 Java SE 代码中为新的持久性单元使用新名称。

于 2013-03-09T17:42:48.823 回答