Skip to content

Commit 41106b7

Browse files
committed
Merge pull request javaee-samples#218 from bartoszmajsak/jpa-custom-converter
Introduced Arquillian-based example for JPA 2.1 custom converter feature
2 parents df6d650 + ae7fa01 commit 41106b7

File tree

23 files changed

+571
-200
lines changed

23 files changed

+571
-200
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,6 @@ local.properties
9090

9191
# PDT-specific
9292
.buildpath
93+
94+
# Testing environment specific
95+
derby.log

jpa/jpa-converter/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
## JPA 2.1 Custom Converter
2+
3+
This project demonstrates following new additions to JPA 2.1
4+
* [Custom converter](http://en.wikibooks.org/wiki/Java_Persistence/Basic_Attributes#Converters_.28JPA_2.1.29) for `CreditCard` object which belongs to Employee
5+
* [JPA 2.1 unified schema generation / db seeding options](https://blogs.oracle.com/arungupta/entry/jpa_2_1_schema_generation) (see `persistence.xml`)
6+
7+
In addition to [Arquillian testing platform](http://arquillian.org) following tools has been used:
8+
* [AssertJ](http://assertj.org) fluent assertions to verify the result of retrieving all objects from the datastore.
9+
* [ShrinkWrap Maven Resolver](https://github.com/shrinkwrap/resolver/blob/master/README.asciidoc) to bundle aforementioned AssertJ together with the test deployment.
10+

jpa/jpa-converter/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
</parent>
1010

1111
<artifactId>jpa-converter</artifactId>
12-
<packaging>war</packaging>
12+
<packaging>jar</packaging>
1313
</project>

jpa/jpa-converter/src/main/java/org/javaee7/jpa/converter/CreditCard.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,25 @@ public String toString() {
3434
return cardNumber;
3535
}
3636

37-
37+
@Override
38+
public boolean equals(Object o) {
39+
if (this == o) {
40+
return true;
41+
}
42+
43+
if (!(o instanceof CreditCard)) {
44+
return false;
45+
}
46+
47+
final CreditCard that = (CreditCard) o;
48+
49+
if (cardNumber != null ? !cardNumber.equals(that.cardNumber) : that.cardNumber != null) return false;
50+
51+
return true;
52+
}
53+
54+
@Override
55+
public int hashCode() {
56+
return cardNumber != null ? cardNumber.hashCode() : 0;
57+
}
3858
}

jpa/jpa-converter/src/main/java/org/javaee7/jpa/converter/Employee.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
})
2121
public class Employee implements Serializable {
2222
private static final long serialVersionUID = 1L;
23+
2324
@Id
2425
private int id;
2526

@@ -35,8 +36,7 @@ public Employee(String name) {
3536
this.name = name;
3637
}
3738

38-
public Employee(int id, String name, CreditCard card) {
39-
this.id = id;
39+
public Employee(String name, CreditCard card) {
4040
this.name = name;
4141
this.card = card;
4242
}
@@ -65,6 +65,31 @@ public void setCard(CreditCard card) {
6565
this.card = card;
6666
}
6767

68+
@Override
69+
public boolean equals(Object o) {
70+
if (this == o) {
71+
return true;
72+
}
73+
74+
if (!(o instanceof Employee)) {
75+
return false;
76+
}
77+
78+
final Employee employee = (Employee) o;
79+
80+
if (card != null ? !card.equals(employee.getCard()) : employee.getCard() != null) return false;
81+
if (!name.equals(employee.getName())) return false;
82+
83+
return true;
84+
}
85+
86+
@Override
87+
public int hashCode() {
88+
int result = name.hashCode();
89+
result = 31 * result + (card != null ? card.hashCode() : 0);
90+
return result;
91+
}
92+
6893
@Override
6994
public String toString() {
7095
return name + " (" + card + ")";

jpa/jpa-converter/src/main/java/org/javaee7/jpa/converter/EmployeeBean.java renamed to jpa/jpa-converter/src/main/java/org/javaee7/jpa/converter/EmployeeRepository.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@
99
* @author Arun Gupta
1010
*/
1111
@Stateless
12-
public class EmployeeBean {
12+
public class EmployeeRepository {
1313

1414
@PersistenceContext
15-
EntityManager em;
15+
private EntityManager em;
1616

1717
public void persist(Employee e) {
1818
em.persist(e);
1919
}
2020

21-
public List<Employee> get() {
21+
public List<Employee> all() {
2222
return em.createNamedQuery("Employee.findAll", Employee.class).getResultList();
2323
}
2424
}

jpa/jpa-converter/src/main/java/org/javaee7/jpa/converter/TestServlet.java

Lines changed: 0 additions & 133 deletions
This file was deleted.
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package org.javaee7.jpa.converter;
2+
3+
import org.jboss.arquillian.container.test.api.Deployment;
4+
import org.jboss.arquillian.junit.Arquillian;
5+
import org.jboss.shrinkwrap.api.Archive;
6+
import org.jboss.shrinkwrap.api.Filters;
7+
import org.jboss.shrinkwrap.api.GenericArchive;
8+
import org.jboss.shrinkwrap.api.ShrinkWrap;
9+
import org.jboss.shrinkwrap.api.asset.FileAsset;
10+
import org.jboss.shrinkwrap.api.importer.ExplodedImporter;
11+
import org.jboss.shrinkwrap.api.spec.JavaArchive;
12+
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
13+
import org.junit.Test;
14+
import org.junit.runner.RunWith;
15+
16+
import javax.inject.Inject;
17+
import java.io.File;
18+
import java.util.List;
19+
20+
import static org.assertj.core.api.Assertions.assertThat;
21+
22+
@RunWith(Arquillian.class)
23+
public class EmployeeRepositoryTest {
24+
25+
@Deployment
26+
public static Archive<?> createDeployment() {
27+
final File[] assertJ = Maven.resolver().loadPomFromFile("pom.xml")
28+
.resolve("org.assertj:assertj-core")
29+
.withTransitivity()
30+
.asFile();
31+
32+
final JavaArchive archive = ShrinkWrap.create(JavaArchive.class, "employee-card-converter-sample.jar")
33+
.addPackage(Employee.class.getPackage())
34+
.addAsManifestResource("test-persistence.xml", "persistence.xml")
35+
.merge(metaInfFolder(), "/META-INF", Filters.include(".*\\.sql"));
36+
mergeDependencies(archive, assertJ);
37+
38+
return archive;
39+
40+
}
41+
42+
@Inject
43+
private EmployeeRepository repository;
44+
45+
@Test
46+
public void should_return_all_employee_records() throws Exception {
47+
// when
48+
final List<Employee> employees = repository.all();
49+
50+
// then
51+
assertThat(employees).hasSize(6)
52+
.contains(employee("Leonard", "11-22-33-44"), employee("Sheldon", "22-33-44-55"),
53+
employee("Penny", "33-44-55-66"), employee("Raj", "44-55-66-77"),
54+
employee("Howard", "55-66-77-88"), employee("Bernadette", "66-77-88-99"));
55+
}
56+
57+
// -- Test utility methods
58+
59+
private static Employee employee(String name, String creditCardNumber) {
60+
final CreditCard creditCard = new CreditCard(creditCardNumber);
61+
return new Employee(name, creditCard);
62+
}
63+
64+
private static void mergeDependencies(JavaArchive archive, File ... dependencies) {
65+
for (File file : dependencies) {
66+
archive.merge(ShrinkWrap.createFromZipFile(JavaArchive.class, file));
67+
}
68+
}
69+
70+
private static GenericArchive metaInfFolder() {
71+
return ShrinkWrap.create(GenericArchive.class)
72+
.as(ExplodedImporter.class)
73+
.importDirectory("src/main/resources/META-INF")
74+
.as(GenericArchive.class);
75+
}
76+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0"?>
2+
<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xmlns="http://jboss.org/schema/arquillian"
4+
xsi:schemaLocation="http://jboss.org/schema/arquillian
5+
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
6+
7+
<engine>
8+
<property name="deploymentExportPath">target/deployment</property>
9+
</engine>
10+
11+
<container qualifier="glassfish-embedded" default="true">
12+
<configuration>
13+
<property name="resourcesXml">src/test/resources-glassfish-embedded/glassfish-resources.xml</property>
14+
<property name="bindHttpPort">9999</property>
15+
</configuration>
16+
</container>
17+
18+
<extension qualifier="persistence">
19+
<property name="dumpData">true</property>
20+
</extension>
21+
22+
<extension qualifier="persistence-script">
23+
<property name="sqlStatementDelimiter">NEW_LINE</property>
24+
<property name="scriptsToExecuteBeforeTest">reset-sequence.sql</property>
25+
</extension>
26+
27+
<extension qualifier="persistence-dbunit">
28+
<property name="excludeTablesFromCleanup">SEQUENCE</property>
29+
<property name="excludeTablesFromComparisonWhenEmptyExpected">SEQUENCE</property>
30+
</extension>
31+
32+
</arquillian>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
3+
<resources>
4+
5+
<jdbc-resource pool-name="ArquillianEmbeddedDerbyPool"
6+
jndi-name="arq/derby"/>
7+
<jdbc-connection-pool name="ArquillianEmbeddedDerbyPool"
8+
res-type="javax.sql.DataSource"
9+
datasource-classname="org.apache.derby.jdbc.EmbeddedDataSource"
10+
is-isolation-level-guaranteed="false">
11+
<property name="databaseName" value="target/db/derby"/>
12+
<property name="createDatabase" value="create"/>
13+
</jdbc-connection-pool>
14+
15+
</resources>
16+
17+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CREATE PROCEDURE DROP_TABLE(IN schemaName varchar(128), IN tableName varchar(128)) PARAMETER STYLE JAVA MODIFIES SQL DATA LANGUAGE JAVA EXTERNAL NAME 'org.jboss.arquillian.integration.persistence.datasource.derby.DerbyDropTable.dropTable'
2+
CALL DROP_TABLE('app', 'SEQUENCE')
3+
DROP PROCEDURE DROP_TABLE
4+
CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR(50) NOT NULL, SEQ_COUNT DECIMAL(15), PRIMARY KEY (SEQ_NAME))
5+
INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 10)

0 commit comments

Comments
 (0)