请帮忙,这让我发疯了。我已经研究了几个小时了,找不到符合我情况的例子。
我正在编写一个非常简单的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模块中,并且它们将无法被客户端访问。
提前致谢!
答案 0 :(得分:0)
让我首先说明,我不清楚为什么你会看到这样的行为,因为我不熟悉你在Glassfish / Java EE运行时所做的事情的预期行为:你正在设置直接连接。相反,在Java EE环境中,您需要“容器管理的持久性单元”[这里是一个猜测:容器将jta-data-source默认为'sun-appserv-samples']。
因此,让Java EE为您管理连接:
在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
使用引用“TestAccountPool”的JNDI名称“jdbc / TestAccountData”定义JDBC资源。
使用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>
如果您还想在Java SE中使用您的实体,那么:
将您最初定义的<persistence-unit> ... </persistence-unit>
添加到 persistence.xml 文件中。
更改第二个持久性单元的名称;它必须是独一无二的。我的工具(eclipse w / glassfish插件)抱怨多个持久性单元;我忽略了这些警告。
将交易类型从“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。
在Java SE代码中将新名称用于新的持久性单元。