Skip to content

Commit 25d30a3

Browse files
authored
Merge pull request #48877 from marko-bekhta/doc/data-repository-nondefault-pu
Document/test how to work with non-default PUs and Jakarta Data repositories
2 parents af8679a + 5e60303 commit 25d30a3

File tree

10 files changed

+180
-24
lines changed

10 files changed

+180
-24
lines changed

docs/src/main/asciidoc/hibernate-orm.adoc

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,10 +1796,10 @@ public interface MyRepository extends CrudRepository<MyEntity, Integer> { // <1>
17961796
17971797
}
17981798
----
1799-
1. To skip the boilerplate definition of CRUD operations,
1799+
<1> To skip the boilerplate definition of CRUD operations,
18001800
we can use one of the available interfaces (e.g. `CrudRepository` or `BasicRepository`).
1801-
2. Adding custom queries with parameters is as easy as providing your query string to the `@Query` annotation.
1802-
3. If the basic CRUD operations from the Jakarta Data interfaces are not enough,
1801+
<2> Adding custom queries with parameters is as easy as providing your query string to the `@Query` annotation.
1802+
<3> If the basic CRUD operations from the Jakarta Data interfaces are not enough,
18031803
we can always add a custom one, in this case a delete operation that removes `MyEntity`s by name.
18041804

18051805
And then the repository can be used as any other bean:
@@ -1817,10 +1817,28 @@ public class MyEntityResource {
18171817
repository.insert(entity);
18181818
}
18191819
1820-
// ...
1820+
// ...
1821+
1822+
}
1823+
----
1824+
1825+
[NOTE]
1826+
====
1827+
When working with non-default persistence units, remember to specify the persistence unit name the repository is targeting
1828+
in the `dataStore` attribute of the repository annotation:
18211829
1830+
[source,java]
1831+
----
1832+
@Repository(dataStore = "other") // <1>
1833+
public interface MyNonDefaultPURepository {
1834+
// ...
18221835
}
18231836
----
1837+
<1> Pass the name of the non-default persistence unit to the repository annotation (`other` in this example).
1838+
1839+
Review the https://jakarta.ee/specifications/data/1.0/apidocs/jakarta.data/jakarta/data/repository/repository#dataStore()[Javadoc of the `@Repository` annotation]
1840+
to learn more about the `dataStore` attribute.
1841+
====
18241842

18251843
Please refer to the corresponding https://hibernate.org/repositories/[Hibernate Data Repositories]
18261844
and https://jakarta.ee/specifications/data/1.0/jakarta-data-1.0[Jakarta Data]
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.quarkus.it.hibernate.jpamodelgen.data;
1+
package io.quarkus.it.hibernate.processor.data;
22

33
import java.util.List;
44

@@ -17,6 +17,10 @@
1717

1818
import org.jboss.resteasy.reactive.RestPath;
1919

20+
import io.quarkus.it.hibernate.processor.data.pudefault.MyEntity;
21+
import io.quarkus.it.hibernate.processor.data.pudefault.MyEntity_;
22+
import io.quarkus.it.hibernate.processor.data.pudefault.MyRepository;
23+
2024
@ApplicationScoped
2125
@Produces("application/json")
2226
@Consumes("application/json")
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package io.quarkus.it.hibernate.processor.data;
2+
3+
import java.util.List;
4+
5+
import jakarta.data.Order;
6+
import jakarta.data.Sort;
7+
import jakarta.enterprise.context.ApplicationScoped;
8+
import jakarta.inject.Inject;
9+
import jakarta.transaction.Transactional;
10+
import jakarta.ws.rs.Consumes;
11+
import jakarta.ws.rs.DELETE;
12+
import jakarta.ws.rs.GET;
13+
import jakarta.ws.rs.NotFoundException;
14+
import jakarta.ws.rs.POST;
15+
import jakarta.ws.rs.Path;
16+
import jakarta.ws.rs.Produces;
17+
18+
import org.jboss.resteasy.reactive.RestPath;
19+
20+
import io.quarkus.it.hibernate.processor.data.puother.MyOtherEntity;
21+
import io.quarkus.it.hibernate.processor.data.puother.MyOtherEntity_;
22+
import io.quarkus.it.hibernate.processor.data.puother.MyOtherRepository;
23+
24+
@ApplicationScoped
25+
@Produces("application/json")
26+
@Consumes("application/json")
27+
@Path("/data/other")
28+
public class MyOtherEntityResource {
29+
30+
@Inject
31+
MyOtherRepository repository;
32+
33+
@POST
34+
@Transactional
35+
public void create(MyOtherEntity entity) {
36+
repository.insert(entity);
37+
}
38+
39+
@GET
40+
public List<MyOtherEntity> get() {
41+
return repository.findAll(Order.by(Sort.asc(MyOtherEntity_.NAME))).toList();
42+
}
43+
44+
@GET
45+
@Transactional
46+
@Path("/by/name/{name}")
47+
public MyOtherEntity getByName(@RestPath String name) {
48+
List<MyOtherEntity> entities = repository.findByName(name);
49+
if (entities.isEmpty()) {
50+
throw new NotFoundException();
51+
}
52+
return entities.get(0);
53+
}
54+
55+
@POST
56+
@Transactional
57+
@Path("/rename/{before}/to/{after}")
58+
public void rename(@RestPath String before, @RestPath String after) {
59+
MyOtherEntity byName = getByName(before);
60+
byName.name = after;
61+
repository.update(byName);
62+
}
63+
64+
@DELETE
65+
@Transactional
66+
@Path("/by/name/{name}")
67+
public void deleteByName(@RestPath String name) {
68+
repository.delete(name);
69+
}
70+
}

integration-tests/hibernate-orm-data/src/main/java/io/quarkus/it/hibernate/jpamodelgen/data/MyEntity.java renamed to integration-tests/hibernate-orm-data/src/main/java/io/quarkus/it/hibernate/processor/data/pudefault/MyEntity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.quarkus.it.hibernate.jpamodelgen.data;
1+
package io.quarkus.it.hibernate.processor.data.pudefault;
22

33
import jakarta.persistence.Column;
44
import jakarta.persistence.Entity;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.quarkus.it.hibernate.jpamodelgen.data;
1+
package io.quarkus.it.hibernate.processor.data.pudefault;
22

33
import java.util.List;
44
import java.util.stream.Stream;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package io.quarkus.it.hibernate.processor.data.puother;
2+
3+
import jakarta.persistence.Column;
4+
import jakarta.persistence.Entity;
5+
import jakarta.persistence.GeneratedValue;
6+
import jakarta.persistence.Id;
7+
8+
@Entity
9+
public class MyOtherEntity {
10+
11+
@Id
12+
@GeneratedValue
13+
public Integer id;
14+
15+
@Column(unique = true)
16+
public String name;
17+
18+
MyOtherEntity() {
19+
}
20+
21+
public MyOtherEntity(String name) {
22+
this.name = name;
23+
}
24+
25+
@Override
26+
public String toString() {
27+
return "MyOrmEntity [id=" + id + ", name=" + name + "]";
28+
}
29+
30+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package io.quarkus.it.hibernate.processor.data.puother;
2+
3+
import java.util.List;
4+
import java.util.stream.Stream;
5+
6+
import jakarta.data.Order;
7+
import jakarta.data.repository.CrudRepository;
8+
import jakarta.data.repository.Delete;
9+
import jakarta.data.repository.Find;
10+
import jakarta.data.repository.Query;
11+
import jakarta.data.repository.Repository;
12+
13+
@Repository(dataStore = "other")
14+
public interface MyOtherRepository extends CrudRepository<MyOtherEntity, Integer> {
15+
16+
@Find
17+
Stream<MyOtherEntity> findAll(Order<MyOtherEntity> order);
18+
19+
@Query("select e from MyOtherEntity e where e.name like :name")
20+
List<MyOtherEntity> findByName(String name);
21+
22+
@Delete
23+
void delete(String name);
24+
25+
}
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,9 @@
11
quarkus.datasource.jdbc.max-size=8
2-
quarkus.hibernate-orm.database.generation=drop-and-create
2+
quarkus.hibernate-orm.packages=io.quarkus.it.hibernate.processor.data.pudefault
3+
quarkus.hibernate-orm.schema-management.strategy=drop-and-create
4+
quarkus.hibernate-orm.schema-management.create-schemas=true
5+
# Define non-default PU so that we can configure a custom JSON format mapper. The default PU is using the default mapper.
6+
quarkus.hibernate-orm."other".datasource=<default>
7+
quarkus.hibernate-orm."other".packages=io.quarkus.it.hibernate.processor.data.puother
8+
quarkus.hibernate-orm."other".schema-management.strategy=drop-and-create
9+
quarkus.hibernate-orm."other".schema-management.create-schemas=true
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.quarkus.it.hibernate.jpamodelgen.data;
1+
package io.quarkus.it.hibernate.processor.data;
22

33
import io.quarkus.test.junit.QuarkusIntegrationTest;
44

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,50 @@
1-
package io.quarkus.it.hibernate.jpamodelgen.data;
1+
package io.quarkus.it.hibernate.processor.data;
22

33
import static io.restassured.RestAssured.given;
44
import static org.hamcrest.CoreMatchers.containsString;
55
import static org.hamcrest.CoreMatchers.equalTo;
66

7-
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.params.ParameterizedTest;
8+
import org.junit.jupiter.params.provider.ValueSource;
89

10+
import io.quarkus.it.hibernate.processor.data.pudefault.MyEntity;
911
import io.quarkus.test.junit.QuarkusTest;
1012
import io.restassured.http.ContentType;
1113

1214
@QuarkusTest
1315
public class HibernateOrmDataTest {
14-
private static final String ROOT = "/data";
1516

16-
@Test
17-
public void staticMetamodel() {
17+
@ValueSource(strings = { "/data", "/data/other" })
18+
@ParameterizedTest
19+
public void repositoryDefaultPu(String root) {
1820
// Create/retrieve
1921
given()
2022
.pathParam("name", "foo")
2123
.contentType(ContentType.JSON)
22-
.when().get(ROOT + "/by/name/{name}")
24+
.when().get(root + "/by/name/{name}")
2325
.then()
2426
.statusCode(404);
2527
given()
2628
.contentType(ContentType.JSON)
27-
.when().get(ROOT)
29+
.when().get(root)
2830
.then()
2931
.statusCode(200)
3032
.body(equalTo("[]"));
3133
given()
3234
.body(new MyEntity("foo"))
3335
.contentType(ContentType.JSON)
34-
.when().post(ROOT)
36+
.when().post(root)
3537
.then()
3638
.statusCode(204);
3739
given()
3840
.pathParam("name", "foo")
3941
.contentType(ContentType.JSON)
40-
.when().get(ROOT + "/by/name/{name}")
42+
.when().get(root + "/by/name/{name}")
4143
.then()
4244
.statusCode(200);
4345
given()
4446
.contentType(ContentType.JSON)
45-
.when().get(ROOT)
47+
.when().get(root)
4648
.then()
4749
.statusCode(200)
4850
.body(containsString("\"foo\""));
@@ -51,34 +53,34 @@ public void staticMetamodel() {
5153
given()
5254
.pathParam("name", "bar")
5355
.contentType(ContentType.JSON)
54-
.when().get(ROOT + "/by/name/{name}")
56+
.when().get(root + "/by/name/{name}")
5557
.then()
5658
.statusCode(404);
5759
given()
5860
.pathParam("before", "foo")
5961
.pathParam("after", "bar")
6062
.contentType(ContentType.JSON)
61-
.when().post(ROOT + "/rename/{before}/to/{after}")
63+
.when().post(root + "/rename/{before}/to/{after}")
6264
.then()
6365
.statusCode(204);
6466
given()
6567
.pathParam("name", "bar")
6668
.contentType(ContentType.JSON)
67-
.when().get(ROOT + "/by/name/{name}")
69+
.when().get(root + "/by/name/{name}")
6870
.then()
6971
.statusCode(200);
7072

7173
// Delete
7274
given()
7375
.pathParam("name", "bar")
7476
.contentType(ContentType.JSON)
75-
.when().delete(ROOT + "/by/name/{name}")
77+
.when().delete(root + "/by/name/{name}")
7678
.then()
7779
.statusCode(204);
7880
given()
7981
.pathParam("name", "bar")
8082
.contentType(ContentType.JSON)
81-
.when().get(ROOT + "/by/name/{name}")
83+
.when().get(root + "/by/name/{name}")
8284
.then()
8385
.statusCode(404);
8486
}

0 commit comments

Comments
 (0)