带独立客户端的EJB忽略persistence.xml(?)

时间:2013-03-08 20:55:06

标签: java-ee jpa entity jpa-2.0 persistence.xml

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

我正在编写一个非常简单的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) {
        ...
    }
}

Account.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模块中,并且它们将无法被客户端访问。

提前致谢!

1 个答案:

答案 0 :(得分:0)

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

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

  1. 在Glassfish中,定义一个ID为“TestAccountPool”的JDBC连接池。您可以从管理面板或命令行执行此操作。这指定了您的datasourceclassname(look here for 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. 使用引用“TestAccountPool”的JNDI名称“jdbc / TestAccountData”定义JDBC资源。

  3. 使用JNDI名称调整 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">
    
        <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>
    

  4. 支持Java SE客户端

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

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

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

    3. 将交易类型从“JTA”更改为“RESOURCE_LOCAL”,或者只需删除它:in a Java EE container the transaction type defaults to JTA (per spec), and in Java SE it defaults to RESOURCE_LOCAL

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