Skip to content

Commit 9d6afdd

Browse files
authored
BAEL-8442 Jakarta Persistence 3.2 (#17832)
* BAEL-8442 Jakarta Persistence 3.2 * BAEL-8442 Jakarta Persistence 3.2 * BAEL-8442 Jakarta Persistence 3.2 * BAEL-8442 Jakarta Persistence 3.2
1 parent 50669a0 commit 9d6afdd

File tree

6 files changed

+361
-0
lines changed

6 files changed

+361
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## JPA in Java
2+
3+
This module contains articles about the Java Persistence API (JPA) in Java.
4+
5+
### Relevant Articles:
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<artifactId>java-jpa-5</artifactId>
7+
<name>java-jpa-5</name>
8+
9+
<parent>
10+
<groupId>com.baeldung</groupId>
11+
<artifactId>persistence-modules</artifactId>
12+
<version>1.0.0-SNAPSHOT</version>
13+
</parent>
14+
15+
<dependencies>
16+
<dependency>
17+
<groupId>org.hibernate.orm</groupId>
18+
<artifactId>hibernate-core</artifactId>
19+
<version>${hibernate.version}</version>
20+
</dependency>
21+
<dependency>
22+
<groupId>com.h2database</groupId>
23+
<artifactId>h2</artifactId>
24+
<version>${h2.version}</version>
25+
</dependency>
26+
27+
<!--Compile time JPA API -->
28+
<dependency>
29+
<groupId>jakarta.persistence</groupId>
30+
<artifactId>jakarta.persistence-api</artifactId>
31+
<version>${jakarta.persistence-api.version}</version>
32+
</dependency>
33+
<dependency>
34+
<groupId>org.apache.commons</groupId>
35+
<artifactId>commons-dbcp2</artifactId>
36+
<version>${commons-dbcp2.version}</version>
37+
<scope>test</scope>
38+
</dependency>
39+
<dependency>
40+
<groupId>com.github.h-thurow</groupId>
41+
<artifactId>simple-jndi</artifactId>
42+
<version>${simple-jndi.version}</version>
43+
<scope>test</scope>
44+
</dependency>
45+
<dependency>
46+
<groupId>org.hibernate.orm</groupId>
47+
<artifactId>hibernate-jpamodelgen</artifactId>
48+
<version>${hibernate.version}</version>
49+
<exclusions>
50+
<exclusion>
51+
<groupId>jakarta.xml.bind</groupId>
52+
<artifactId>jakarta.xml.bind-api</artifactId>
53+
</exclusion>
54+
</exclusions>
55+
</dependency>
56+
</dependencies>
57+
58+
<build>
59+
<plugins>
60+
<plugin>
61+
<groupId>org.apache.maven.plugins</groupId>
62+
<artifactId>maven-compiler-plugin</artifactId>
63+
<version>${maven-compiler-plugin.version}</version>
64+
<configuration>
65+
<compilerArgument>-proc:none</compilerArgument>
66+
<source>17</source>
67+
<target>17</target>
68+
</configuration>
69+
</plugin>
70+
<plugin>
71+
<groupId>org.bsc.maven</groupId>
72+
<artifactId>maven-processor-plugin</artifactId>
73+
<version>${maven-processor-plugin.version}</version>
74+
<executions>
75+
<execution>
76+
<id>process</id>
77+
<goals>
78+
<goal>process</goal>
79+
</goals>
80+
<phase>generate-sources</phase>
81+
<configuration>
82+
<outputDirectory>target/metamodel</outputDirectory>
83+
<processors>
84+
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
85+
</processors>
86+
</configuration>
87+
</execution>
88+
</executions>
89+
</plugin>
90+
</plugins>
91+
</build>
92+
93+
<properties>
94+
<maven-processor-plugin.version>3.3.3</maven-processor-plugin.version>
95+
<h2.version>2.1.214</h2.version>
96+
<jakarta.persistence-api.version>3.2.0</jakarta.persistence-api.version>
97+
<hibernate.version>7.0.0.Beta1</hibernate.version>
98+
<commons-dbcp2.version>2.12.0</commons-dbcp2.version>
99+
<simple-jndi.version>0.23.0</simple-jndi.version>
100+
</properties>
101+
102+
</project>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.baeldung.jakarta;
2+
3+
import jakarta.persistence.Entity;
4+
import jakarta.persistence.Id;
5+
import jakarta.persistence.NamedQuery;
6+
7+
@Entity
8+
@NamedQuery(name = "Employee.byDepartment", query = "FROM Employee WHERE department = :department", resultClass = Employee.class)
9+
public class Employee {
10+
11+
@Id
12+
private Long id;
13+
14+
private String fullName;
15+
16+
private String department;
17+
18+
public Long getId() {
19+
return id;
20+
}
21+
22+
public void setId(Long id) {
23+
this.id = id;
24+
}
25+
26+
public String getFullName() {
27+
return fullName;
28+
}
29+
30+
public void setFullName(String fullName) {
31+
this.fullName = fullName;
32+
}
33+
34+
public String getDepartment() {
35+
return department;
36+
}
37+
38+
public void setDepartment(String department) {
39+
this.department = department;
40+
}
41+
42+
public Employee() {
43+
}
44+
45+
public Employee(Long id, String fullName, String department) {
46+
this.id = id;
47+
this.fullName = fullName;
48+
this.department = department;
49+
}
50+
51+
}
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
package com.baeldung.jakarta;
2+
3+
import static com.baeldung.jakarta.Employee_.QUERY_EMPLOYEE_BY_DEPARTMENT;
4+
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
import static org.junit.jupiter.api.Assertions.assertNotNull;
6+
import static org.junit.jupiter.api.Assertions.assertNull;
7+
8+
import java.sql.Connection;
9+
import java.util.List;
10+
import java.util.Map;
11+
12+
import jakarta.persistence.EntityManager;
13+
import jakarta.persistence.EntityManagerFactory;
14+
import jakarta.persistence.PersistenceConfiguration;
15+
import jakarta.persistence.TypedQuery;
16+
import jakarta.persistence.TypedQueryReference;
17+
import jakarta.persistence.metamodel.EntityType;
18+
19+
import javax.naming.InitialContext;
20+
21+
import org.apache.commons.dbcp2.BasicDataSource;
22+
import org.junit.After;
23+
import org.junit.Before;
24+
import org.junit.Test;
25+
import org.junit.jupiter.api.Assertions;
26+
27+
public class JakartaPersistenceApiTest {
28+
29+
private static EntityManagerFactory emf;
30+
31+
private static EntityManager em;
32+
33+
@Before
34+
public void setUp() throws Exception {
35+
BasicDataSource dataSource = new BasicDataSource();
36+
dataSource.setDriverClassName("org.h2.Driver");
37+
dataSource.setUrl("jdbc:h2:mem:jakartaPersistenceApiTest");
38+
dataSource.setUsername("sa");
39+
40+
InitialContext ctx = new InitialContext();
41+
ctx.bind("java:comp/env/jdbc/EmployeeData", dataSource);
42+
43+
emf = createEntityManagerFactory();
44+
em = emf.createEntityManager();
45+
46+
emf.getSchemaManager()
47+
.create(true);
48+
49+
EntityType<?> employeeEntity = emf.getMetamodel()
50+
.entity(Employee.class);
51+
assertNotNull(employeeEntity, "Employee entity should be part of the metamodel");
52+
53+
emf.runInTransaction(em -> {
54+
em.persist(new Employee(1L, "John Smith", "Finance"));
55+
em.persist(new Employee(2L, "Tom Riddle", "Art"));
56+
em.persist(new Employee(3L, "Harry Potter", "Magic"));
57+
em.persist(new Employee(4L, "Jade Gringer", "Education"));
58+
em.persist(new Employee(5L, "Cole Powell", "Science"));
59+
em.persist(new Employee(6L, "Jane Guducu", "Engineering"));
60+
em.persist(new Employee(7L, "Tony Blair", "Engineering"));
61+
});
62+
}
63+
64+
@After
65+
public void teardown() {
66+
emf.runInTransaction(em -> em.runWithConnection(connection -> {
67+
try (var stmt = ((Connection) connection).createStatement()) {
68+
stmt.execute("delete from employee");
69+
} catch (Exception e) {
70+
Assertions.fail("JDBC operation failed");
71+
}
72+
}));
73+
74+
emf.close();
75+
}
76+
77+
@Test
78+
public void whenUsingPersistenceConfiguration_thenEntityManagerFactoryIsCreated() {
79+
assertNotNull(emf);
80+
}
81+
82+
@Test
83+
public void whenRunInTransactionAndCallInTransaction_thenTheEntityManagerWorksWithTransaction() {
84+
emf.runInTransaction(em -> em.runWithConnection(connection -> {
85+
try (var stmt = ((Connection) connection).createStatement()) {
86+
stmt.execute("INSERT INTO employee (id, fullName, department) VALUES (8, 'Jane Smith', 'HR')");
87+
} catch (Exception e) {
88+
Assertions.fail("JDBC operation failed");
89+
}
90+
}));
91+
92+
var employee = emf.callInTransaction(em -> em.find(Employee.class, 8L));
93+
assertNotNull(employee);
94+
assertEquals("Jane Smith", employee.getFullName());
95+
}
96+
97+
@Test
98+
public void whenUsingEnhancedJpql_thenNewFeaturesWorks() {
99+
Employee employee = emf.callInTransaction(em -> em.createQuery("from Employee where fullName = 'Tony Blair'", Employee.class)
100+
.getSingleResult());
101+
102+
assertNotNull(employee);
103+
}
104+
105+
@Test
106+
public void givenNamedQuery_whenQueriedByDepartment_thenReturnCorrectEmployee() {
107+
108+
Map<String, TypedQueryReference<Employee>> namedQueries = emf.getNamedQueries(Employee.class);
109+
110+
List<Employee> employees = em.createQuery(namedQueries.get(QUERY_EMPLOYEE_BY_DEPARTMENT))
111+
.setParameter("department", "Science")
112+
.getResultList();
113+
114+
assertEquals(1, employees.size());
115+
}
116+
117+
@Test
118+
public void whenFindEmployeeWithEntityGraph_thenReturnEmployeeWithDepartment() {
119+
var employeeGraph = emf.callInTransaction(em -> em.createEntityGraph(Employee.class));
120+
employeeGraph.addAttributeNode(Employee_.department);
121+
122+
var employee = emf.callInTransaction(em -> em.find(employeeGraph, 7L));
123+
assertNotNull(employee);
124+
assertEquals("Engineering", employee.getDepartment());
125+
}
126+
127+
@Test
128+
public void whenCastFullNameToInteger_thenReturnCorrectResult() {
129+
emf.runInTransaction(em -> em.persist(new Employee(11L, "123456", "Art")));
130+
131+
TypedQuery<Integer> query = em.createQuery("select cast(e.fullName as integer) from Employee e where e.id = 11", Integer.class);
132+
Integer result = query.getSingleResult();
133+
134+
assertEquals(123456, result);
135+
}
136+
137+
@Test
138+
public void whenLeftAndRightFullName_thenReturnSubstring() {
139+
TypedQuery<String> query = em.createQuery("select left(e.fullName, 3) from Employee e where e.id = 2", String.class);
140+
String result = query.getSingleResult();
141+
142+
assertEquals("Tom", result);
143+
144+
query = em.createQuery("select right(e.fullName, 6) from Employee e where e.id = 2", String.class);
145+
result = query.getSingleResult();
146+
147+
assertEquals("Riddle", result);
148+
}
149+
150+
@Test
151+
public void whenReplaceFullName_thenReturnModifiedName() {
152+
153+
TypedQuery<String> query = em.createQuery("select replace(e.fullName, 'Jade', 'Jane') from Employee e where e.id = 4", String.class);
154+
String result = query.getSingleResult();
155+
156+
assertEquals("Jane Gringer", result);
157+
}
158+
159+
@Test
160+
public void whenUseIdFunction_thenReturnEmployeeId() {
161+
TypedQuery<Long> query = em.createQuery("select id(e) from Employee e where e.fullName = 'John Smith'", Long.class);
162+
Long result = query.getSingleResult();
163+
164+
assertEquals(1L, result);
165+
}
166+
167+
@Test
168+
public void whenSortEmployeesByFullName_thenReturnSortedList() {
169+
emf.runInTransaction(em -> {
170+
em.persist(new Employee(21L, "alice", "HR"));
171+
em.persist(new Employee(22L, "Bob", "Engineering"));
172+
em.persist(new Employee(23L, null, "Finance"));
173+
em.persist(new Employee(24L, "charlie", "HR"));
174+
});
175+
176+
TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e ORDER BY lower(e.fullName) ASC NULLS FIRST, e.id DESC", Employee.class);
177+
178+
List<Employee> sortedEmployees = query.getResultList();
179+
180+
// Assertions
181+
assertEquals(11, sortedEmployees.size());
182+
assertNull(sortedEmployees.get(0)
183+
.getFullName());
184+
assertEquals("alice", sortedEmployees.get(1)
185+
.getFullName());
186+
assertEquals("Bob", sortedEmployees.get(2)
187+
.getFullName());
188+
assertEquals("charlie", sortedEmployees.get(3)
189+
.getFullName());
190+
}
191+
192+
private EntityManagerFactory createEntityManagerFactory() {
193+
return new PersistenceConfiguration("EmployeeData").jtaDataSource("java:comp/env/jdbc/EmployeeData")
194+
.managedClass(Employee.class)
195+
.property(PersistenceConfiguration.LOCK_TIMEOUT, 5000)
196+
.createEntityManagerFactory();
197+
}
198+
199+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
java.naming.factory.initial=org.osjava.sj.SimpleContextFactory
2+
org.osjava.sj.root=src/test/resources
3+
org.osjava.sj.jndi.shared=true

persistence-modules/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
<module>java-jpa-2</module>
5050
<module>java-jpa-3</module>
5151
<module>java-jpa-4</module>
52+
<module>java-jpa-5</module>
5253
<module>java-mongodb-2</module> <!-- long running -->
5354
<module>java-mongodb-3</module> <!-- long running -->
5455
<module>java-mongodb-queries</module> <!-- long running -->

0 commit comments

Comments
 (0)