Skip to content

Commit

Permalink
Add test specifically for using Hibernate ORM in a non-quarkus way
Browse files Browse the repository at this point in the history
  • Loading branch information
yrodiere committed Dec 4, 2023
1 parent 7d1642e commit 36bb87a
Show file tree
Hide file tree
Showing 6 changed files with 285 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package io.quarkus.it.jpa.nonquarkus;

import java.io.IOException;
import java.util.List;
import java.util.UUID;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.PersistenceUnit;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

@Path("/non-quarkus")
@ApplicationScoped
public class NonQuarkusApiResource {

@PersistenceUnit
EntityManagerFactory entityManagerFactory;

@GET
@Path("test")
public String test() throws IOException {
//Cleanup any existing data:
deleteAllPerson(entityManagerFactory);

//Store some well known Person instances we can then test on:
storeTestPersons(entityManagerFactory);

//Load all persons and run some checks on the query results:
verifyListOfExistingPersons(entityManagerFactory);

//Try a JPA named query:
verifyJPANamedQuery(entityManagerFactory);

deleteAllPerson(entityManagerFactory);

return "OK";
}

private static void verifyJPANamedQuery(final EntityManagerFactory emf) {
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
TypedQuery<Person> typedQuery = em.createNamedQuery(
"get_person_by_name", Person.class);
typedQuery.setParameter("name", "Quarkus");
final Person singleResult = typedQuery.getSingleResult();

if (!singleResult.getName().equals("Quarkus")) {
throw new RuntimeException("Wrong result from named JPA query");
}

transaction.commit();
em.close();
}

private static void verifyListOfExistingPersons(final EntityManagerFactory emf) {
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
listExistingPersons(em);
transaction.commit();
em.close();
}

private static void storeTestPersons(final EntityManagerFactory emf) {
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
persistNewPerson(em, "Gizmo");
persistNewPerson(em, "Quarkus");
persistNewPerson(em, "Hibernate ORM");
transaction.commit();
em.close();
}

private static void deleteAllPerson(final EntityManagerFactory emf) {
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
em.createNativeQuery("Delete from Person").executeUpdate();
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).orderBy(cb.asc(from.get("name")));
TypedQuery<Person> q = em.createQuery(cq);
List<Person> allpersons = q.getResultList();
if (allpersons.size() != 3) {
throw new RuntimeException("Incorrect number of results");
}
if (!allpersons.get(0).getName().equals("Gizmo")) {
throw new RuntimeException("Incorrect order of results");
}
StringBuilder sb = new StringBuilder("list of stored Person names:\n\t");
for (Person p : allpersons) {
p.describeFully(sb);
sb.append("\n\t");
if (p.getStatus() != Status.LIVING) {
throw new RuntimeException("Incorrect status " + p);
}
}
sb.append("\nList complete.\n");
System.out.print(sb);
}

private static void persistNewPerson(EntityManager entityManager, String name) {
Person person = new Person();
person.setName(name);
person.setStatus(Status.LIVING);
person.setAddress(new SequencedAddress("Street " + randomName()));
entityManager.persist(person);
}

private static String randomName() {
return UUID.randomUUID().toString();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package io.quarkus.it.jpa.nonquarkus;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.NamedQuery;

@Entity
@NamedQuery(name = "get_person_by_name", query = "select p from Person p where name = :name")
public class Person {

private long id;
private String name;
private SequencedAddress address;
private Status status;

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 Status getStatus() {
return status;
}

public void setStatus(Status status) {
this.status = status;
}

public void describeFully(StringBuilder sb) {
sb.append("Person with id=").append(id).append(", name='").append(name).append("', status='").append(status)
.append("', address { ");
getAddress().describeFully(sb);
sb.append(" }");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.quarkus.it.jpa.nonquarkus;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.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("'");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package io.quarkus.it.jpa.nonquarkus;

public enum Status {
LIVING,
DECEASED
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.quarkus.it.jpa.nonquarkus;

import io.quarkus.test.junit.QuarkusIntegrationTest;

@QuarkusIntegrationTest
public class NonQuarkusApiInGraalITCase extends NonQuarkusApiTest {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.quarkus.it.jpa.nonquarkus;

import static io.restassured.RestAssured.given;
import static org.hamcrest.core.Is.is;

import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusTest;

/**
* Test usage of JPA in a way that is not recommended with Quarkus:
* creating the entity manager manually, using `em.getTransaction()`, ...
* <p>
* This is mainly tested to ensure migration is relatively easy, like we test `persistence.xml` support:
* we expect developers to move to `@Inject EntityManager em;`
* and `QuarkusTransaction`/`UserTransaction` for best results.
*/
@QuarkusTest
public class NonQuarkusApiTest {

@Test
public void test() {
given().queryParam("expectedSchema", "SCHEMA1")
.when().get("/jpa-test/non-quarkus/test").then()
.body(is("OK"))
.statusCode(200);
}

}

0 comments on commit 36bb87a

Please sign in to comment.