mirror of
https://github.com/jlengrand/quarkus.git
synced 2026-03-10 08:41:22 +00:00
Merge pull request #22 from emmanuelbernard/JPABoot
Integrate JPA into Shamrock
This commit is contained in:
173
examples/jpa-strict/pom.xml
Normal file
173
examples/jpa-strict/pom.xml
Normal file
@@ -0,0 +1,173 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>shamrock-examples-parent</artifactId>
|
||||
<groupId>org.jboss.shamrock</groupId>
|
||||
<version>1.0.0.Alpha1-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>shamrock-strict-jpa-example</artifactId>
|
||||
<description>An example that only contains JPA related tests running in strict mode</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jboss.shamrock</groupId>
|
||||
<artifactId>shamrock-jaxrs-deployment</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.shamrock</groupId>
|
||||
<artifactId>shamrock-jpa-deployment</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql-protean</artifactId>
|
||||
<version>42.2.5-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- test dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.jboss.shamrock</groupId>
|
||||
<artifactId>shamrock-junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.shamrock</groupId>
|
||||
<artifactId>shamrock-graal</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish</groupId>
|
||||
<artifactId>javax.json</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>shamrock-maven-plugin</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>build</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>io.fabric8</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
<version>0.26.1</version>
|
||||
<configuration>
|
||||
<images>
|
||||
<image>
|
||||
<name>postgres:10.5</name>
|
||||
<alias>postgresql</alias>
|
||||
<run>
|
||||
<env>
|
||||
<POSTGRES_USER>hibernate_orm_test</POSTGRES_USER>
|
||||
<POSTGRES_PASSWORD>hibernate_orm_test</POSTGRES_PASSWORD>
|
||||
<POSTGRES_DB>hibernate_orm_test</POSTGRES_DB>
|
||||
</env>
|
||||
<ports>
|
||||
<port>5432:5432</port>
|
||||
</ports>
|
||||
<wait>
|
||||
<tcp>
|
||||
<mode>mapped</mode>
|
||||
<ports>
|
||||
<port>5432</port>
|
||||
</ports>
|
||||
</tcp>
|
||||
<time>10000</time>
|
||||
</wait>
|
||||
</run>
|
||||
</image>
|
||||
</images>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>docker-start</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>stop</goal>
|
||||
<goal>start</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>docker-stop</id>
|
||||
<phase>post-integration-test</phase>
|
||||
<goals>
|
||||
<goal>stop</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>native-image</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>!no-native</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>shamrock-maven-plugin</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>native-image</id>
|
||||
<goals>
|
||||
<goal>native-image</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<reportErrorsAtRuntime>false</reportErrorsAtRuntime>
|
||||
<cleanupServer>true</cleanupServer>
|
||||
<enableHttpUrlHandler>true</enableHttpUrlHandler>
|
||||
<!-- Requires Protean Graal fork to work, will fail otherwise
|
||||
<enableRetainedHeapReporting>true</enableRetainedHeapReporting>
|
||||
<enableCodeSizeReporting>true</enableCodeSizeReporting>
|
||||
-->
|
||||
<graalvmHome>${graalvmHome}</graalvmHome>
|
||||
<enableJni>false</enableJni>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.jboss.shamrock.example;
|
||||
|
||||
public class MainMethod {
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
Class.forName("org.jboss.shamrock.runtime.RuntimeRunner");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.jboss.shamrock.example.jpa;
|
||||
|
||||
import javax.persistence.Embeddable;
|
||||
|
||||
/**
|
||||
* This is an enmarked @Embeddable class.
|
||||
* Let's see if just being referenced by the main entity is enough to be detected.
|
||||
*
|
||||
* @author Emmanuel Bernard emmanuel@hibernate.org
|
||||
*/
|
||||
//FIXME : this used to be non-annotated explicitly for testing purposes
|
||||
// added the annotation as it's illegal according to the ORM metadata validation
|
||||
@Embeddable
|
||||
public class Address {
|
||||
private String street1;
|
||||
private String street2;
|
||||
private String zipCode;
|
||||
|
||||
public String getStreet1() {
|
||||
return street1;
|
||||
}
|
||||
|
||||
public void setStreet1(String street1) {
|
||||
this.street1 = street1;
|
||||
}
|
||||
|
||||
public String getStreet2() {
|
||||
return street2;
|
||||
}
|
||||
|
||||
public void setStreet2(String street2) {
|
||||
this.street2 = street2;
|
||||
}
|
||||
|
||||
public String getZipCode() {
|
||||
return zipCode;
|
||||
}
|
||||
|
||||
public void setZipCode(String zipCode) {
|
||||
this.zipCode = zipCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.jboss.shamrock.example.jpa;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard emmanuel@hibernate.org
|
||||
*/
|
||||
public class Animal {
|
||||
private double weight;
|
||||
|
||||
public double getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(double weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.jboss.shamrock.example.jpa;
|
||||
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* Used to test reflection references for JPA
|
||||
*
|
||||
* @author Emmanuel Bernard emmanuel@hibernate.org
|
||||
*/
|
||||
@Entity
|
||||
public class Customer extends Human {
|
||||
@Id
|
||||
// no getter explicitly to test field only reflective access
|
||||
private Long id;
|
||||
|
||||
private Address address;
|
||||
private WorkAddress workAddress;
|
||||
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
// Address is referenced but not marked as @Embeddable
|
||||
@Embedded
|
||||
public Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public WorkAddress getWorkAddress() {
|
||||
return workAddress;
|
||||
}
|
||||
|
||||
public void setWorkAddress(WorkAddress workAddress) {
|
||||
this.workAddress = workAddress;
|
||||
}
|
||||
|
||||
public void setAddress(Address address) {
|
||||
this.address = address;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.jboss.shamrock.example.jpa;
|
||||
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
/**
|
||||
* Mapped superclass test
|
||||
*
|
||||
* @author Emmanuel Bernard emmanuel@hibernate.org
|
||||
*/
|
||||
@MappedSuperclass
|
||||
public class Human extends Animal {
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package org.jboss.shamrock.example.jpa;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import javax.persistence.Persistence;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Various tests for the JPA integration. WARNING: these tests will ONLY pass in Substrate, as it also verifies
|
||||
* reflection non-functionality.
|
||||
*/
|
||||
@WebServlet(name = "JPATestBootstrapEndpoint", urlPatterns = "/jpa/testbootstrap")
|
||||
public class JPATestBootstrapEndpoint extends HttpServlet {
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
try {
|
||||
testStoreLoadOnJPA();
|
||||
} catch (Exception e) {
|
||||
reportException("Oops, shit happened, No boot for you!", e, resp);
|
||||
}
|
||||
|
||||
resp.getWriter().write("OK");
|
||||
}
|
||||
|
||||
public void testStoreLoadOnJPA() throws Exception {
|
||||
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("templatePU");
|
||||
System.out.println("Hibernate EntityManagerFactory: booted");
|
||||
|
||||
doStuffWithHibernate(entityManagerFactory);
|
||||
|
||||
entityManagerFactory.close();
|
||||
System.out.println("Hibernate EntityManagerFactory: shut down");
|
||||
|
||||
}
|
||||
|
||||
private static void doStuffWithHibernate(EntityManagerFactory entityManagerFactory) {
|
||||
EntityManager em = entityManagerFactory.createEntityManager();
|
||||
EntityTransaction transaction = em.getTransaction();
|
||||
transaction.begin();
|
||||
|
||||
persistNewPerson(em);
|
||||
|
||||
listExistingPersons(em);
|
||||
|
||||
transaction.commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
private static void listExistingPersons(EntityManager em) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
|
||||
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
|
||||
Root<Person> from = cq.from(Person.class);
|
||||
cq.select(from);
|
||||
TypedQuery<Person> q = em.createQuery(cq);
|
||||
List<Person> allpersons = q.getResultList();
|
||||
StringBuilder sb = new StringBuilder("list of stored Person names:\n\t");
|
||||
for (Person p : allpersons) {
|
||||
p.describeFully(sb);
|
||||
sb.append("\n\t");
|
||||
}
|
||||
sb.append("\nList complete.\n");
|
||||
System.out.print(sb);
|
||||
}
|
||||
|
||||
private static void persistNewPerson(EntityManager entityManager) {
|
||||
Person person = new Person();
|
||||
person.setName(randomName());
|
||||
person.setAddress(new SequencedAddress("Street " + randomName()));
|
||||
entityManager.persist(person);
|
||||
}
|
||||
|
||||
private static String randomName() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
private void reportException(String errorMessage, final Exception e, final HttpServletResponse resp) throws IOException {
|
||||
final PrintWriter writer = resp.getWriter();
|
||||
if (errorMessage != null) {
|
||||
writer.write(errorMessage);
|
||||
writer.write(" ");
|
||||
}
|
||||
writer.write(e.toString());
|
||||
writer.append("\n\t");
|
||||
e.printStackTrace(writer);
|
||||
writer.append("\n\t");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package org.jboss.shamrock.example.jpa;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Various tests for the JPA integration.
|
||||
* WARNING: these tests will ONLY pass in Substrate, as it also verifies reflection non-functionality.
|
||||
*/
|
||||
@WebServlet(name = "JPATestReflectionEndpoint", urlPatterns = "/jpa/testreflection")
|
||||
public class JPATestReflectionEndpoint extends HttpServlet {
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
makeSureNonEntityAreDCE(resp);
|
||||
makeSureEntitiesAreAccessibleViaReflection(resp);
|
||||
makeSureNonAnnotatedEmbeddableAreAccessibleViaReflection(resp);
|
||||
makeSureAnnotatedEmbeddableAreAccessibleViaReflection(resp);
|
||||
makeSureClassAreAccessibleViaReflection("org.jboss.shamrock.example.jpa.Human", "Unable to enlist @MappedSuperclass", resp);
|
||||
makeSureClassAreAccessibleViaReflection("org.jboss.shamrock.example.jpa.Animal", "Unable to enlist entity superclass", resp);
|
||||
resp.getWriter().write("OK");
|
||||
}
|
||||
|
||||
private void makeSureClassAreAccessibleViaReflection(String className, String errorMessage, HttpServletResponse resp) throws IOException {
|
||||
try {
|
||||
className = getTrickedClassName(className);
|
||||
|
||||
Class<?> custClass = Class.forName(className);
|
||||
Object instance = custClass.newInstance();
|
||||
}
|
||||
catch (Exception e) {
|
||||
reportException(errorMessage, e, resp);
|
||||
}
|
||||
}
|
||||
|
||||
private void makeSureEntitiesAreAccessibleViaReflection(HttpServletResponse resp) throws IOException {
|
||||
try {
|
||||
String className = getTrickedClassName(org.jboss.shamrock.example.jpa.Customer.class.getName());
|
||||
|
||||
Class<?> custClass = Class.forName(className);
|
||||
Object instance = custClass.newInstance();
|
||||
Field id = custClass.getDeclaredField("id");
|
||||
id.setAccessible(true);
|
||||
if (id.get(instance) != null) {
|
||||
resp.getWriter().write("id should be reachable and null");
|
||||
}
|
||||
Method setter = custClass.getDeclaredMethod("setName", String.class);
|
||||
Method getter = custClass.getDeclaredMethod("getName");
|
||||
setter.invoke(instance, "Emmanuel");
|
||||
if (! "Emmanuel".equals(getter.invoke(instance))) {
|
||||
resp.getWriter().write("getter / setter should be reachable and usable");
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
reportException(e, resp);
|
||||
}
|
||||
}
|
||||
|
||||
private void makeSureAnnotatedEmbeddableAreAccessibleViaReflection(HttpServletResponse resp) throws IOException {
|
||||
try {
|
||||
String className = getTrickedClassName(org.jboss.shamrock.example.jpa.WorkAddress.class.getName());
|
||||
|
||||
Class<?> custClass = Class.forName(className);
|
||||
Object instance = custClass.newInstance();
|
||||
Method setter = custClass.getDeclaredMethod("setCompany", String.class);
|
||||
Method getter = custClass.getDeclaredMethod("getCompany");
|
||||
setter.invoke(instance, "Red Hat");
|
||||
if (! "Red Hat".equals(getter.invoke(instance))) {
|
||||
resp.getWriter().write("@Embeddable embeddable should be reachable and usable");
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
reportException(e, resp);
|
||||
}
|
||||
}
|
||||
private void makeSureNonAnnotatedEmbeddableAreAccessibleViaReflection(HttpServletResponse resp) throws IOException {
|
||||
try {
|
||||
String className = getTrickedClassName(org.jboss.shamrock.example.jpa.Address.class.getName());
|
||||
|
||||
Class<?> custClass = Class.forName(className);
|
||||
Object instance = custClass.newInstance();
|
||||
Method setter = custClass.getDeclaredMethod("setStreet1", String.class);
|
||||
Method getter = custClass.getDeclaredMethod("getStreet1");
|
||||
setter.invoke(instance, "1 rue du General Leclerc");
|
||||
if (! "1 rue du General Leclerc".equals(getter.invoke(instance))) {
|
||||
resp.getWriter().write("Non @Embeddable embeddable getter / setter should be reachable and usable");
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
reportException(e, resp);
|
||||
}
|
||||
}
|
||||
|
||||
private void makeSureNonEntityAreDCE(HttpServletResponse resp) {
|
||||
try {
|
||||
String className = getTrickedClassName(org.jboss.shamrock.example.jpa.NotAnEntityNotReferenced.class.getName());
|
||||
|
||||
Class<?> custClass = Class.forName(className);
|
||||
resp.getWriter().write("Should not be able to find a non referenced non entity class");
|
||||
Object instance = custClass.newInstance();
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Expected outcome
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trick SubstrateVM not to detect a simple use of Class.forname
|
||||
*/
|
||||
private String getTrickedClassName(String className) {
|
||||
className = className + " ITrickYou";
|
||||
className = className.subSequence(0, className.indexOf(' ')).toString();
|
||||
return className;
|
||||
}
|
||||
|
||||
private void reportException(final Exception e, final HttpServletResponse resp) throws IOException {
|
||||
reportException(null, e, resp);
|
||||
}
|
||||
|
||||
private void reportException(String errorMessage, final Exception e, final HttpServletResponse resp) throws IOException {
|
||||
final PrintWriter writer = resp.getWriter();
|
||||
if ( errorMessage != null ) {
|
||||
writer.write(errorMessage);
|
||||
writer.write(" ");
|
||||
}
|
||||
writer.write(e.toString());
|
||||
writer.append("\n\t");
|
||||
e.printStackTrace(writer);
|
||||
writer.append("\n\t");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.jboss.shamrock.example.jpa;
|
||||
|
||||
/**
|
||||
* Should not be referenced by the code
|
||||
* So be dead code eliminated.
|
||||
* Used to test that entities get referenced but not non entities
|
||||
*
|
||||
* @author Emmanuel Bernard emmanuel@hibernate.org
|
||||
*/
|
||||
public class NotAnEntityNotReferenced {
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package org.jboss.shamrock.example.jpa;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
@Entity
|
||||
public class Person {
|
||||
|
||||
private long id;
|
||||
private String name;
|
||||
private SequencedAddress address;
|
||||
|
||||
public Person() {
|
||||
}
|
||||
|
||||
public Person(long id, String name, SequencedAddress address) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="personSeq")
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
||||
public SequencedAddress getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(SequencedAddress address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public void describeFully(StringBuilder sb) {
|
||||
sb.append( "Person with id=" ).append( id ).append( ", name='" ).append( name ).append( "', address { " );
|
||||
getAddress().describeFully( sb );
|
||||
sb.append( " }" );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.jboss.shamrock.example.jpa;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class SequencedAddress {
|
||||
|
||||
private long id;
|
||||
private String street;
|
||||
|
||||
public SequencedAddress() {
|
||||
}
|
||||
|
||||
public SequencedAddress(String street) {
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="addressSeq")
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
public void setStreet(String name) {
|
||||
this.street = name;
|
||||
}
|
||||
|
||||
public void describeFully(StringBuilder sb) {
|
||||
sb.append( "Address with id=" ).append( id ).append( ", street='" ).append( street ).append( "'" );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.jboss.shamrock.example.jpa;
|
||||
|
||||
import javax.persistence.Embeddable;
|
||||
|
||||
/**
|
||||
* Class marked @Embeddable explicitly so it is picked up.
|
||||
*
|
||||
* @author Emmanuel Bernard emmanuel@hibernate.org
|
||||
*/
|
||||
@Embeddable
|
||||
public class WorkAddress {
|
||||
private String company;
|
||||
|
||||
public String getCompany() {
|
||||
return company;
|
||||
}
|
||||
|
||||
public void setCompany(String company) {
|
||||
this.company = company;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<persistence 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"
|
||||
version="2.1">
|
||||
|
||||
<persistence-unit name="templatePU" transaction-type="RESOURCE_LOCAL">
|
||||
|
||||
<description>Hibernate test case template Persistence Unit</description>
|
||||
|
||||
<properties>
|
||||
<!-- intentionally using worse case so that we can optimise for this -->
|
||||
<property name="hibernate.archive.autodetection" value="class, hbm"/>
|
||||
|
||||
<!-- Connection specific -->
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL95Dialect"/>
|
||||
<property name="hibernate.connection.url" value="jdbc:postgresql:hibernate_orm_test"/>
|
||||
<property name="hibernate.connection.username" value="hibernate_orm_test"/>
|
||||
<property name="hibernate.connection.password" value="hibernate_orm_test"/>
|
||||
|
||||
<!-- Tuning and debugging -->
|
||||
<property name="hibernate.connection.pool_size" value="2"/>
|
||||
<property name="hibernate.show_sql" value="false"/>
|
||||
<property name="hibernate.format_sql" value="false"/>
|
||||
|
||||
<!--
|
||||
Optimistically create the tables;
|
||||
will cause background errors being logged if they already exist,
|
||||
but is practical to retain existing data across runs (or create as needed) -->
|
||||
<!-- drop-and-create create-only -->
|
||||
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
|
||||
|
||||
<property name="javax.persistence.validation.mode" value="NONE"/>
|
||||
</properties>
|
||||
|
||||
</persistence-unit>
|
||||
</persistence>
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.jboss.shamrock.example.test;
|
||||
|
||||
import org.jboss.shamrock.example.testutils.URLTester;
|
||||
import org.jboss.shamrock.junit.GraalTest;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Test reflection around JPA entities
|
||||
*
|
||||
* @author Emmanuel Bernard emmanuel@hibernate.org
|
||||
*/
|
||||
@RunWith(GraalTest.class)
|
||||
public class JPABootstrapInGraalITCase {
|
||||
|
||||
@Test
|
||||
public void testFieldAndGetterReflectionOnEntityFromServlet() throws Exception {
|
||||
assertEquals("OK", URLTester.relative("jpa/testbootstrap").invokeURL().asString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.jboss.shamrock.example.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.jboss.shamrock.example.testutils.URLTester;
|
||||
import org.jboss.shamrock.junit.GraalTest;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/**
|
||||
* Test reflection around JPA entities
|
||||
*
|
||||
* @author Emmanuel Bernard emmanuel@hibernate.org
|
||||
*/
|
||||
@RunWith(GraalTest.class)
|
||||
public class JPAReflectionInGraalITCase {
|
||||
|
||||
@Test
|
||||
public void testFieldAndGetterReflectionOnEntityFromServlet() throws Exception {
|
||||
assertEquals("OK", URLTester.relative("jpa/testreflection").invokeURL().asString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package org.jboss.shamrock.example.test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import javax.persistence.Persistence;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.jboss.shamrock.example.jpa.Person;
|
||||
import org.jboss.shamrock.example.jpa.SequencedAddress;
|
||||
import org.jboss.shamrock.junit.ShamrockTest;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@RunWith(ShamrockTest.class)
|
||||
public class JPAStoreLoadTestCase {
|
||||
|
||||
@Test
|
||||
public void testStoreLoadOnJPA() throws Exception {
|
||||
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory( "templatePU" );
|
||||
System.out.println( "Hibernate EntityManagerFactory: booted" );
|
||||
|
||||
doStuffWithHibernate( entityManagerFactory );
|
||||
|
||||
entityManagerFactory.close();
|
||||
System.out.println( "Hibernate EntityManagerFactory: shut down" );
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void doStuffWithHibernate(EntityManagerFactory entityManagerFactory) {
|
||||
EntityManager em = entityManagerFactory.createEntityManager();
|
||||
EntityTransaction transaction = em.getTransaction();
|
||||
transaction.begin();
|
||||
|
||||
persistNewPerson( em );
|
||||
|
||||
listExistingPersons( em );
|
||||
|
||||
transaction.commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
private static void listExistingPersons(EntityManager em) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
|
||||
CriteriaQuery<Person> cq = cb.createQuery( Person.class );
|
||||
Root<Person> from = cq.from( Person.class );
|
||||
cq.select( from );
|
||||
TypedQuery<Person> q = em.createQuery( cq );
|
||||
List<Person> allpersons = q.getResultList();
|
||||
StringBuilder sb = new StringBuilder( "list of stored Person names:\n\t" );
|
||||
for ( Person p : allpersons ) {
|
||||
p.describeFully( sb );
|
||||
sb.append( "\n\t" );
|
||||
}
|
||||
sb.append( "\nList complete.\n" );
|
||||
System.out.print( sb );
|
||||
}
|
||||
|
||||
private static void persistNewPerson(EntityManager entityManager) {
|
||||
Person person = new Person();
|
||||
person.setName( randomName() );
|
||||
person.setAddress( new SequencedAddress( "Street " + randomName() ) );
|
||||
entityManager.persist( person );
|
||||
}
|
||||
|
||||
private static String randomName() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.jboss.shamrock.example.testutils;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.json.JsonReader;
|
||||
|
||||
public interface URLResponse {
|
||||
|
||||
String asString();
|
||||
|
||||
InputStream asInputStream();
|
||||
|
||||
JsonReader asJsonReader();
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package org.jboss.shamrock.example.testutils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
import javax.json.Json;
|
||||
import javax.json.JsonReader;
|
||||
|
||||
/**
|
||||
* Convenience class to invoke an URL and return the response.
|
||||
*/
|
||||
public final class URLTester {
|
||||
|
||||
private final URL fullURL;
|
||||
|
||||
private URLTester(final URL fullURL) {
|
||||
this.fullURL = fullURL;
|
||||
}
|
||||
|
||||
public static URLTester relative(final String relativePath) {
|
||||
final URL uri;
|
||||
try {
|
||||
uri = new URL("http://localhost:8080/" + relativePath);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return new URLTester(uri);
|
||||
}
|
||||
|
||||
private URLResponse privateInvokeURL() throws IOException {
|
||||
URLConnection connection = fullURL.openConnection();
|
||||
InputStream in = connection.getInputStream();
|
||||
byte[] buf = new byte[100];
|
||||
int r;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
while ((r = in.read(buf)) > 0) {
|
||||
out.write(buf, 0, r);
|
||||
}
|
||||
return new URLResponseAdapter(out);
|
||||
}
|
||||
|
||||
public URLResponse invokeURL() {
|
||||
try {
|
||||
return privateInvokeURL();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class URLResponseAdapter implements URLResponse {
|
||||
|
||||
private final ByteArrayOutputStream buffer;
|
||||
|
||||
public URLResponseAdapter(final ByteArrayOutputStream buffer) {
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new String(buffer.toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asString() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream asInputStream() {
|
||||
return new ByteArrayInputStream(buffer.toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonReader asJsonReader() {
|
||||
return Json.createReader(asInputStream());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
<module>permissive</module>
|
||||
<module>shared-library</module>
|
||||
<module>strict</module>
|
||||
<module>jpa-strict</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -144,6 +144,55 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>io.fabric8</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
<version>0.26.1</version>
|
||||
<configuration>
|
||||
<images>
|
||||
<image>
|
||||
<name>postgres:10.5</name>
|
||||
<alias>postgresql</alias>
|
||||
<run>
|
||||
<env>
|
||||
<POSTGRES_USER>hibernate_orm_test</POSTGRES_USER>
|
||||
<POSTGRES_PASSWORD>hibernate_orm_test</POSTGRES_PASSWORD>
|
||||
<POSTGRES_DB>hibernate_orm_test</POSTGRES_DB>
|
||||
</env>
|
||||
<ports>
|
||||
<port>5432:5432</port>
|
||||
</ports>
|
||||
<wait>
|
||||
<tcp>
|
||||
<mode>mapped</mode>
|
||||
<ports>
|
||||
<port>5432</port>
|
||||
</ports>
|
||||
</tcp>
|
||||
<time>10000</time>
|
||||
</wait>
|
||||
</run>
|
||||
</image>
|
||||
</images>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>docker-start</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>stop</goal>
|
||||
<goal>start</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>docker-stop</id>
|
||||
<phase>post-integration-test</phase>
|
||||
<goals>
|
||||
<goal>stop</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
package org.jboss.shamrock.example.jpa;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Various tests for the JPA integration.
|
||||
* WARNING: these tests will ONLY pass in Substrate, as it also verifies reflection non-functionality.
|
||||
*/
|
||||
@WebServlet(name = "JPATestBootstrapEndpoint", urlPatterns = "/jpa/testbootstrap")
|
||||
public class JPATestBootstrapEndpoint extends HttpServlet {
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
try {
|
||||
testStoreLoadOnJPA();
|
||||
}
|
||||
catch (Exception e) {
|
||||
reportException("Oops, shit happened, No boot for you!", e, resp);
|
||||
}
|
||||
|
||||
|
||||
resp.getWriter().write("OK");
|
||||
}
|
||||
|
||||
|
||||
public void testStoreLoadOnJPA() throws Exception {
|
||||
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory( "templatePU" );
|
||||
System.out.println( "Hibernate EntityManagerFactory: booted" );
|
||||
|
||||
doStuffWithHibernate( entityManagerFactory );
|
||||
|
||||
entityManagerFactory.close();
|
||||
System.out.println( "Hibernate EntityManagerFactory: shut down" );
|
||||
|
||||
}
|
||||
|
||||
private static void doStuffWithHibernate(EntityManagerFactory entityManagerFactory) {
|
||||
EntityManager em = entityManagerFactory.createEntityManager();
|
||||
EntityTransaction transaction = em.getTransaction();
|
||||
transaction.begin();
|
||||
|
||||
persistNewPerson( em );
|
||||
|
||||
listExistingPersons( em );
|
||||
|
||||
transaction.commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
private static void listExistingPersons(EntityManager em) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
|
||||
CriteriaQuery<Person> cq = cb.createQuery( Person.class );
|
||||
Root<Person> from = cq.from( Person.class );
|
||||
cq.select( from );
|
||||
TypedQuery<Person> q = em.createQuery( cq );
|
||||
List<Person> allpersons = q.getResultList();
|
||||
StringBuilder sb = new StringBuilder( "list of stored Person names:\n\t" );
|
||||
for ( Person p : allpersons ) {
|
||||
p.describeFully( sb );
|
||||
sb.append( "\n\t" );
|
||||
}
|
||||
sb.append( "\nList complete.\n" );
|
||||
System.out.print( sb );
|
||||
}
|
||||
|
||||
private static void persistNewPerson(EntityManager entityManager) {
|
||||
Person person = new Person();
|
||||
person.setName( randomName() );
|
||||
person.setAddress( new SequencedAddress( "Street " + randomName() ) );
|
||||
entityManager.persist( person );
|
||||
}
|
||||
|
||||
private static String randomName() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
private void reportException(final Exception e, final HttpServletResponse resp) throws IOException {
|
||||
reportException(null, e, resp);
|
||||
}
|
||||
|
||||
private void reportException(String errorMessage, final Exception e, final HttpServletResponse resp) throws IOException {
|
||||
final PrintWriter writer = resp.getWriter();
|
||||
if ( errorMessage != null ) {
|
||||
writer.write(errorMessage);
|
||||
writer.write(" ");
|
||||
}
|
||||
writer.write(e.toString());
|
||||
writer.append("\n\t");
|
||||
e.printStackTrace(writer);
|
||||
writer.append("\n\t");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package org.jboss.shamrock.example.jpa;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
@Entity
|
||||
public class Person {
|
||||
|
||||
private long id;
|
||||
private String name;
|
||||
private SequencedAddress address;
|
||||
|
||||
public Person() {
|
||||
}
|
||||
|
||||
public Person(long id, String name, SequencedAddress address) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="personSeq")
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
||||
public SequencedAddress getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(SequencedAddress address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public void describeFully(StringBuilder sb) {
|
||||
sb.append( "Person with id=" ).append( id ).append( ", name='" ).append( name ).append( "', address { " );
|
||||
getAddress().describeFully( sb );
|
||||
sb.append( " }" );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.jboss.shamrock.example.jpa;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class SequencedAddress {
|
||||
|
||||
private long id;
|
||||
private String street;
|
||||
|
||||
public SequencedAddress() {
|
||||
}
|
||||
|
||||
public SequencedAddress(String street) {
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="addressSeq")
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
public void setStreet(String name) {
|
||||
this.street = name;
|
||||
}
|
||||
|
||||
public void describeFully(StringBuilder sb) {
|
||||
sb.append( "Address with id=" ).append( id ).append( ", street='" ).append( street ).append( "'" );
|
||||
}
|
||||
}
|
||||
36
examples/strict/src/main/resources/META-INF/persistence.xml
Normal file
36
examples/strict/src/main/resources/META-INF/persistence.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<persistence 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"
|
||||
version="2.1">
|
||||
|
||||
<persistence-unit name="templatePU" transaction-type="RESOURCE_LOCAL">
|
||||
|
||||
<description>Hibernate test case template Persistence Unit</description>
|
||||
|
||||
<properties>
|
||||
<!-- intentionally using worse case so that we can optimise for this -->
|
||||
<property name="hibernate.archive.autodetection" value="class, hbm"/>
|
||||
|
||||
<!-- Connection specific -->
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL95Dialect"/>
|
||||
<property name="hibernate.connection.url" value="jdbc:postgresql:hibernate_orm_test"/>
|
||||
<property name="hibernate.connection.username" value="hibernate_orm_test"/>
|
||||
<property name="hibernate.connection.password" value="hibernate_orm_test"/>
|
||||
|
||||
<!-- Tuning and debugging -->
|
||||
<property name="hibernate.connection.pool_size" value="2"/>
|
||||
<property name="hibernate.show_sql" value="false"/>
|
||||
<property name="hibernate.format_sql" value="false"/>
|
||||
|
||||
<!--
|
||||
Optimistically create the tables;
|
||||
will cause background errors being logged if they already exist,
|
||||
but is practical to retain existing data across runs (or create as needed) -->
|
||||
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
|
||||
|
||||
<property name="javax.persistence.validation.mode" value="NONE"/>
|
||||
</properties>
|
||||
|
||||
</persistence-unit>
|
||||
</persistence>
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.jboss.shamrock.example.test;
|
||||
|
||||
import org.jboss.shamrock.example.testutils.URLTester;
|
||||
import org.jboss.shamrock.junit.GraalTest;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Test reflection around JPA entities
|
||||
*
|
||||
* @author Emmanuel Bernard emmanuel@hibernate.org
|
||||
*/
|
||||
@RunWith(GraalTest.class)
|
||||
public class JPABootstrapInGraalITCase {
|
||||
|
||||
@Test
|
||||
public void testFieldAndGetterReflectionOnEntityFromServlet() throws Exception {
|
||||
assertEquals("OK", URLTester.relative("jpa/testbootstrap").invokeURL().asString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package org.jboss.shamrock.example.test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import javax.persistence.Persistence;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.jboss.shamrock.example.jpa.Person;
|
||||
import org.jboss.shamrock.example.jpa.SequencedAddress;
|
||||
import org.jboss.shamrock.junit.ShamrockTest;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@RunWith(ShamrockTest.class)
|
||||
public class JPAStoreLoadTestCase {
|
||||
|
||||
@Test
|
||||
public void testStoreLoadOnJPA() throws Exception {
|
||||
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory( "templatePU" );
|
||||
System.out.println( "Hibernate EntityManagerFactory: booted" );
|
||||
|
||||
doStuffWithHibernate( entityManagerFactory );
|
||||
|
||||
entityManagerFactory.close();
|
||||
System.out.println( "Hibernate EntityManagerFactory: shut down" );
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void doStuffWithHibernate(EntityManagerFactory entityManagerFactory) {
|
||||
EntityManager em = entityManagerFactory.createEntityManager();
|
||||
EntityTransaction transaction = em.getTransaction();
|
||||
transaction.begin();
|
||||
|
||||
persistNewPerson( em );
|
||||
|
||||
listExistingPersons( em );
|
||||
|
||||
transaction.commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
private static void listExistingPersons(EntityManager em) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
|
||||
CriteriaQuery<Person> cq = cb.createQuery( Person.class );
|
||||
Root<Person> from = cq.from( Person.class );
|
||||
cq.select( from );
|
||||
TypedQuery<Person> q = em.createQuery( cq );
|
||||
List<Person> allpersons = q.getResultList();
|
||||
StringBuilder sb = new StringBuilder( "list of stored Person names:\n\t" );
|
||||
for ( Person p : allpersons ) {
|
||||
p.describeFully( sb );
|
||||
sb.append( "\n\t" );
|
||||
}
|
||||
sb.append( "\nList complete.\n" );
|
||||
System.out.print( sb );
|
||||
}
|
||||
|
||||
private static void persistNewPerson(EntityManager entityManager) {
|
||||
Person person = new Person();
|
||||
person.setName( randomName() );
|
||||
person.setAddress( new SequencedAddress( "Street " + randomName() ) );
|
||||
entityManager.persist( person );
|
||||
}
|
||||
|
||||
private static String randomName() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package org.jboss.shamrock.jpa;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.hibernate.tuple.component.PojoComponentTuplizer;
|
||||
import org.jboss.shamrock.deployment.ProcessorContext;
|
||||
|
||||
/**
|
||||
@@ -29,6 +30,7 @@ final class HibernateReflectiveNeeds {
|
||||
private void registerAll() {
|
||||
//Various well known needs:
|
||||
simpleConstructor(org.hibernate.tuple.entity.PojoEntityTuplizer.class);
|
||||
allConstructors(org.hibernate.tuple.component.PojoComponentTuplizer.class);
|
||||
simpleConstructor(org.hibernate.persister.entity.SingleTableEntityPersister.class);
|
||||
simpleConstructor(org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorBuilderImpl.class);
|
||||
simpleConstructor(org.hibernate.id.enhanced.SequenceStyleGenerator.class);
|
||||
@@ -53,6 +55,11 @@ final class HibernateReflectiveNeeds {
|
||||
simpleConstructor("org.postgresql.Driver");
|
||||
}
|
||||
|
||||
private void allConstructors(final Class clazz) {
|
||||
//FIXME simpleConstructor is not optimized yet to only enlist the no-arg constructor
|
||||
simpleConstructor(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register classes which we know will only need to be created via their no-arg constructor
|
||||
* @param clazz
|
||||
|
||||
@@ -64,6 +64,7 @@ final class JpaJandexScavenger {
|
||||
JPADeploymentTemplate template = context.getRecordingProxy(JPADeploymentTemplate.class);
|
||||
collector.dumpAllToJPATemplate(template);
|
||||
template.enlistPersistenceUnit();
|
||||
template.callHibernateFeatureInit();
|
||||
}
|
||||
|
||||
return collector;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.jboss.shamrock.jpa;
|
||||
|
||||
import org.hibernate.protean.Hibernate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -16,4 +18,8 @@ public class JPADeploymentTemplate {
|
||||
public void enlistPersistenceUnit() {
|
||||
System.out.println("List of entities \n" + entities.toString());
|
||||
}
|
||||
|
||||
public void callHibernateFeatureInit() {
|
||||
Hibernate.featureInit();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user