如何在JTA事务模式下配置EJB/JPA? [英] How to configure EJB/JPA in JTA transaction mode?
问题描述
推荐答案
1-在应用程序服务器中设置数据源: 为了在您的webapp中使用JTA模式配置JPA,您需要首先设置一个数据源。您可以从应用程序服务器(Glassfish/Payara/.)设置数据源。但建议通过您的Web App设置数据源。按照以下步骤通过Maven Web应用程序设置GlassFish或Payara的数据源:
- 在项目文件夹中新建文件夹(不是包),名称为";Setup";。
- 创建一个新的xml文件并将其命名为";glassfish-resources.xml";,并将其保存在&q;Setup&q;文件夹中。然后编写以下内容:
<?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-resource enabled="true" jndi-name="**jdbc/DBDev01**" object-type="user" pool-name="**jdbc/DBDev01-ConnectionPool**">
<description/>
</jdbc-resource>
<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.mariadb.jdbc.MariaDbDataSource**"
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="**jdbc/DBDev01-ConnectionPool**"
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="URL" value="**jdbc:mariadb://XXX.XXX.XXX.XXX:XXXX/DB_NAME**"/>
<property name="User" value="**USERNAME**"/>
<property name="Password" value="**PASSWORD**"/>
</jdbc-connection-pool>
</resources>
注意:*之间的所有值都需要根据您的设置进行修改。 此文件将在部署WebApp后由您的应用服务器(Glassfish/Payara)加载。对于Payara用户,您也可以使用";payara-resource ces.xml";命名文件,但只需稍作修改。引用:Payara Deployment Descriptors.
2-在WEB-INF/web.xml中添加数据源的资源引用: 您需要通过在WEB-INF/web.xml文件中添加以下内容,在您的WebApp中为DataSource添加资源引用:
<web-app .....>
......
<resource-ref>
<description>**DBDev01**</description>
<res-ref-name>**jdbc/DBDev01**</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<!-- <res-sharing-scope>Shareable</res-sharing-scope> -->
</resource-ref>
</web-app>
注意:res-ref-name应与您在Glassfish资源文件中为数据源选择的名称完全匹配。
3-配置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="**MyDB**" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<!-- List all Entity classes -->
<class>**com.MyEntityClassName**</class>
<jta-data-source>**jdbc/DBDev01**</jta-data-source>
<!-- you can list all entity classes you need and set this value to true. or set this value to false to include other entity clases -->
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
</persistence>
注意:如果您希望使用JTA作为交易类型,则必须定义jta-data-source。在没有定义JTA数据源的情况下,开发人员在试图连接到数据库的属性中添加DB URL、用户名和密码是一个常见的错误。这将不起作用,并且将导致您的应用程序服务器使用已定义的默认数据源,该数据源通常是H2数据库。
4-将JDBC客户端作为依赖项添加到POM.xml:
<dependency>
<!-- This is for MariaDB. You should change it if you are using other kind of DB like MySQL or Oracle DB -->
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>2.7.2</version>
</dependency>
5-享受您的代码: 正在编写sessionBean:
@Stateless
public class StudentManager
{
/* Notes:
1.you should use the same name exactly that defined in Persistence.xml file.
2.You can not use @PersistenceUnit with JTA. only use @PersistenceContext with JTA.
*/
@PersistenceContext(unitName="MyDB")
private EntityManager em;
public StudentManager()
{
}
public void persist(Student student) {
em.persist(student);
em.close();
}
}
写入TestController:
@Named
@SessionScoped
public class TestController
{
@Inject
private StudentManager studentManager;
private String message = "";
public void test()
{
Student student = new Student();
int x = ThreadLocalRandom.current().nextInt(0, 1000);
so.setCode(x);
so.setName("John");
studentManager.persist(so);
/*Note:we used studentManager directly without constructing.
writing studentManager = new StudentManager() is a common mistake and will lead you to get a null EntityManager.*/
this.setMessage("A new Student already saved successful with Code:" + Student.getCode());
}
常见问题:应该使用@Inject还是@EJB?here is the answer
一个简单的JSF测试页面:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<h:commandButton value="Test Save a Student over JTA" action="#{testController.test()}" />
<br />
<h:outputLabel for="message" value="#{test.message}" />
</h:form>
</h:body>
</html>
这篇关于如何在JTA事务模式下配置EJB/JPA?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!