| Lesson 4 | Software Requirements (JPA Transactions) |
| Objective | Set up a modern environment for JPA and transactions using either a full Jakarta EE runtime or Apache Tomcat. |
This course uses the Jakarta Persistence (JPA) API and transactions (JTA or resource-local). Choose one of the two supported setups below.
java -version.Use a Jakarta EE-compliant server (e.g., WildFly, Payara, Open Liberty). These provide JPA and a JTA transaction manager out-of-the-box.
WAR (or EAR if required).persistence.xml (JTA)
<persistence xmlns="https://jakarta.ee/xml/ns/persistence" version="3.1">
<persistence-unit name="appPU" transaction-type="JTA">
<jta-data-source>jdbc/AppDataSource</jta-data-source>
<properties>
<!-- Provider auto-discovery is typical; optionally declare -->
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="jakarta.persistence.schema-generation.database.action" value="none"/>
</properties>
</persistence-unit>
</persistence>
Notes: The server supplies JPA provider and JTA TM. Use a JNDI DataSource (jta-data-source).
Tomcat does not include JPA/JTA. You have two options:
EntityTransaction.META-INF/context.xml (or conf/context.xml)
<Context>
<Resource name="jdbc/AppDataSource"
auth="Container"
type="javax.sql.DataSource"
maxTotal="50" maxIdle="10"
username="appuser" password="secret"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@//dbhost:1521/ORCLPDB1"/>
</Context>
persistence.xml
<persistence xmlns="https://jakarta.ee/xml/ns/persistence" version="3.1">
<persistence-unit name="appPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="jakarta.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
<property name="jakarta.persistence.jdbc.url" value="jdbc:oracle:thin:@//dbhost:1521/ORCLPDB1"/>
<property name="jakarta.persistence.jdbc.user" value="appuser"/>
<property name="jakarta.persistence.jdbc.password" value="secret"/>
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.show_sql" value="false"/>
</properties>
</persistence-unit>
</persistence>
Transaction usage (RESOURCE_LOCAL):
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
try {
tx.begin();
// ... JPA work ...
tx.commit();
} catch (RuntimeException ex) {
if (tx.isActive()) tx.rollback();
throw ex;
} finally {
em.close();
}
Add a JTA TM (e.g., Narayana) and configure its integration so EntityManager joins JTA transactions. Then use transaction-type="JTA" and a <jta-data-source> in persistence.xml. This path is more complex and intended for multi-resource (XA) or container-style management on Tomcat.
Hibernate + HikariCP (RESOURCE_LOCAL)
<dependencies>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency> <!-- Choose your JDBC driver -->
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc11</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
For a full Jakarta EE server, you usually do not include the JPA API/provider-use the server-supplied modules and just add your JDBC driver if required by the server.
java -version prints an LTS JDK (21/23).mvn -v or gradle -v.tnsping for Oracle, or a simple JDBC test).