Skip to content

Commit 166995f

Browse files
committed
Allow connecting a Panache entity to more than one PU (at most one blocking, one reactive)
1 parent 96eb6f2 commit 166995f

File tree

3 files changed

+63
-13
lines changed

3 files changed

+63
-13
lines changed

extensions/panache/hibernate-panache/deployment/src/main/java/io/quarkus/hibernate/panache/deployment/EntityToPersistenceUnitBuildItem.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ public final class EntityToPersistenceUnitBuildItem extends MultiBuildItem {
1010

1111
private final String entityClass;
1212
private final String persistenceUnitName;
13+
private final String reactivePersistenceUnitName;
1314

14-
public EntityToPersistenceUnitBuildItem(String entityClass, String persistenceUnitName) {
15+
public EntityToPersistenceUnitBuildItem(String entityClass, String persistenceUnitName,
16+
String reactivePersistenceUnitName) {
1517
this.entityClass = entityClass;
1618
this.persistenceUnitName = persistenceUnitName;
19+
this.reactivePersistenceUnitName = reactivePersistenceUnitName;
1720
}
1821

1922
public String getEntityClass() {
@@ -23,4 +26,8 @@ public String getEntityClass() {
2326
public String getPersistenceUnitName() {
2427
return persistenceUnitName;
2528
}
29+
30+
public String getReactivePersistenceUnitName() {
31+
return reactivePersistenceUnitName;
32+
}
2633
}
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,47 @@
11
package io.quarkus.hibernate.panache.deployment;
22

3-
import java.util.Collections;
43
import java.util.HashMap;
4+
import java.util.List;
55
import java.util.Map;
66
import java.util.Optional;
77
import java.util.Set;
88
import java.util.TreeMap;
99

1010
import io.quarkus.hibernate.orm.deployment.JpaModelPersistenceUnitMappingBuildItem;
11+
import io.quarkus.hibernate.orm.deployment.PersistenceUnitDescriptorBuildItem;
1112

1213
//FIXME: duplicate with ORM and probably HR
1314
public final class EntityToPersistenceUnitUtil {
1415

16+
@FunctionalInterface
17+
public interface TriConsumer {
18+
void consume(String entity, String persistenceUnit, String reactivePersistenceUnit);
19+
}
20+
1521
private EntityToPersistenceUnitUtil() {
1622
}
1723

1824
/**
1925
* Given the candidate entities, return a map with the persistence unit that single contains them
2026
* or throw an exception if any of the candidates is part of more than one persistence unit
2127
*/
22-
public static Map<String, String> determineEntityPersistenceUnits(
28+
public static void determineEntityPersistenceUnits(
2329
Optional<JpaModelPersistenceUnitMappingBuildItem> jpaModelPersistenceUnitMapping,
24-
Set<String> candidates, String source) {
30+
List<PersistenceUnitDescriptorBuildItem> descriptors,
31+
Set<String> candidates, String source,
32+
TriConsumer consumer) {
2533
if (jpaModelPersistenceUnitMapping.isEmpty()) {
26-
return Collections.emptyMap();
34+
return;
2735
}
2836
Map<String, String> result = new HashMap<>();
2937
Map<String, Set<String>> collectedEntityToPersistenceUnits = jpaModelPersistenceUnitMapping.get()
3038
.getEntityToPersistenceUnits();
3139

40+
Map<String, PersistenceUnitDescriptorBuildItem> descriptorsMap = new HashMap<>();
41+
for (PersistenceUnitDescriptorBuildItem descriptor : descriptors) {
42+
descriptorsMap.put(descriptor.getPersistenceUnitName(), descriptor);
43+
}
44+
3245
Map<String, Set<String>> violatingEntities = new TreeMap<>();
3346

3447
for (Map.Entry<String, Set<String>> entry : collectedEntityToPersistenceUnits.entrySet()) {
@@ -40,10 +53,39 @@ public static Map<String, String> determineEntityPersistenceUnits(
4053
continue;
4154
}
4255

43-
if (selectedPersistenceUnits.size() == 1) {
44-
result.put(entityName, selectedPersistenceUnits.iterator().next());
45-
} else {
46-
violatingEntities.put(entityName, selectedPersistenceUnits);
56+
String persistenceUnit = null;
57+
String reactivePersistenceUnit = null;
58+
if (selectedPersistenceUnits.size() > 0) {
59+
boolean error = false;
60+
// collect at most one of blocking/reactive PU
61+
for (String selectedPersistenceUnit : selectedPersistenceUnits) {
62+
PersistenceUnitDescriptorBuildItem descriptor = descriptorsMap.get(selectedPersistenceUnit);
63+
if (descriptor == null) {
64+
throw new IllegalStateException(String.format("Cannot find descriptor unit named %s for entity %s",
65+
selectedPersistenceUnit, entityName));
66+
}
67+
if (descriptor.isReactive()) {
68+
if (reactivePersistenceUnit != null) {
69+
error = true;
70+
break;
71+
} else {
72+
reactivePersistenceUnit = selectedPersistenceUnit;
73+
}
74+
} else {
75+
if (persistenceUnit != null) {
76+
error = true;
77+
break;
78+
} else {
79+
persistenceUnit = selectedPersistenceUnit;
80+
}
81+
}
82+
}
83+
if (error) {
84+
violatingEntities.put(entityName, selectedPersistenceUnits);
85+
} else if (persistenceUnit != null || reactivePersistenceUnit != null) {
86+
// ignore the entity if it belongs to no PU, though I doubt that happens
87+
consumer.consume(entityName, persistenceUnit, reactivePersistenceUnit);
88+
}
4789
}
4890
}
4991

@@ -57,7 +99,5 @@ public static Map<String, String> determineEntityPersistenceUnits(
5799
throw new IllegalStateException(message.toString());
58100
}
59101
}
60-
61-
return result;
62102
}
63103
}

extensions/panache/hibernate-panache/deployment/src/main/java/io/quarkus/hibernate/panache/deployment/PanacheHibernateResourceProcessor.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import io.quarkus.deployment.builditem.FeatureBuildItem;
3737
import io.quarkus.deployment.util.JandexUtil;
3838
import io.quarkus.hibernate.orm.deployment.JpaModelPersistenceUnitMappingBuildItem;
39+
import io.quarkus.hibernate.orm.deployment.PersistenceUnitDescriptorBuildItem;
3940
import io.quarkus.hibernate.orm.deployment.spi.AdditionalJpaModelBuildItem;
4041
import io.quarkus.hibernate.panache.PanacheEntityMarker;
4142
import io.quarkus.hibernate.panache.PanacheRepositoryQueries;
@@ -112,6 +113,7 @@ void build(
112113
BuildProducer<BytecodeTransformerBuildItem> transformers,
113114
List<PanacheEntityClassBuildItem> entityClasses,
114115
Optional<JpaModelPersistenceUnitMappingBuildItem> jpaModelPersistenceUnitMapping,
116+
List<PersistenceUnitDescriptorBuildItem> descriptors,
115117
List<PanacheMethodCustomizerBuildItem> methodCustomizersBuildItems,
116118
BuildProducer<EntityToPersistenceUnitBuildItem> entityToPersistenceUnit) {
117119

@@ -136,8 +138,8 @@ void build(
136138

137139
panacheEntities.addAll(modelClasses);
138140

139-
determineEntityPersistenceUnits(jpaModelPersistenceUnitMapping, panacheEntities, "Panache")
140-
.forEach((e, pu) -> entityToPersistenceUnit.produce(new EntityToPersistenceUnitBuildItem(e, pu)));
141+
determineEntityPersistenceUnits(jpaModelPersistenceUnitMapping, descriptors, panacheEntities, "Panache", (e, pu,
142+
reactivePU) -> entityToPersistenceUnit.produce(new EntityToPersistenceUnitBuildItem(e, pu, reactivePU)));
141143
}
142144

143145
@BuildStep
@@ -147,6 +149,7 @@ void recordEntityToPersistenceUnit(Optional<JpaModelPersistenceUnitMappingBuildI
147149
CombinedIndexBuildItem index,
148150
PanacheHibernateRecorder recorder) throws ClassNotFoundException {
149151
// PU
152+
// FIXME: for now, this ignores the reactive PUs, but reactive PUs are not supported yet by Panache Reactive
150153
Map<String, String> map = new HashMap<>();
151154
for (EntityToPersistenceUnitBuildItem item : items) {
152155
map.put(item.getEntityClass(), item.getPersistenceUnitName());

0 commit comments

Comments
 (0)