Skip to content

Commit 85c9a19

Browse files
author
Houssam El Mansouri
committed
Add support for Hibernate's hibernate.hbm2ddl.extra_physical_table_types
1 parent 60a8278 commit 85c9a19

File tree

5 files changed

+78
-11
lines changed

5 files changed

+78
-11
lines changed

extensions/hibernate-orm/deployment/src/test/java/io/quarkus/hibernate/orm/config/properties/ConfigPropertiesTest.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22

33
import static org.assertj.core.api.Assertions.assertThat;
44

5+
import java.util.List;
6+
57
import jakarta.inject.Inject;
68
import jakarta.transaction.Transactional;
79

810
import org.hibernate.FlushMode;
911
import org.hibernate.Session;
12+
import org.hibernate.cfg.AvailableSettings;
1013
import org.jboss.shrinkwrap.api.ShrinkWrap;
1114
import org.jboss.shrinkwrap.api.spec.JavaArchive;
1215
import org.junit.jupiter.api.Test;
@@ -32,7 +35,9 @@ public class ConfigPropertiesTest {
3235
.overrideConfigKey("quarkus.hibernate-orm.\"overrides\".packages", MyEntityForOverridesPU.class.getPackageName())
3336
.overrideConfigKey("quarkus.hibernate-orm.\"overrides\".datasource", "<default>")
3437
// Overrides to test that Quarkus configuration properties are taken into account
35-
.overrideConfigKey("quarkus.hibernate-orm.\"overrides\".flush.mode", "always");
38+
.overrideConfigKey("quarkus.hibernate-orm.\"overrides\".flush.mode", "always")
39+
.overrideConfigKey("quarkus.hibernate-orm.\"overrides\".database.extra-physical-table-types",
40+
"MATERIALIZED VIEW,FOREIGN TABLE");
3641

3742
@Inject
3843
Session sessionForDefaultPU;
@@ -48,4 +53,19 @@ public void propertiesAffectingSession() {
4853
assertThat(sessionForOverridesPU.getHibernateFlushMode()).isEqualTo(FlushMode.ALWAYS);
4954
}
5055

56+
@Test
57+
@Transactional
58+
public void extraPhysicalTableTypes() {
59+
Object extraPhysicalTableTypes = sessionForOverridesPU.getProperties()
60+
.get(AvailableSettings.EXTRA_PHYSICAL_TABLE_TYPES);
61+
62+
assertThat(extraPhysicalTableTypes).isNotNull();
63+
assertThat(extraPhysicalTableTypes).isInstanceOf(List.class);
64+
65+
@SuppressWarnings("unchecked")
66+
List<String> tableTypes = (List<String>) extraPhysicalTableTypes;
67+
68+
assertThat(tableTypes).containsExactly("MATERIALIZED VIEW", "FOREIGN TABLE");
69+
}
70+
5171
}

extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/FastBootHibernatePersistenceProvider.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,13 @@ private static void injectRuntimeConfiguration(HibernateOrmRuntimeConfigPersiste
483483
"When using offline mode with `quarkus.hibernate-orm.database.start-offline=true`, the schema management strategy `quarkus.hibernate-orm.schema-management.strategy` must be unset or set to `none`");
484484
}
485485

486+
// Pass extraPhysicalTableTypes configuration
487+
List<String> extraPhysicalTableTypes = persistenceUnitConfig.schemaManagement().extraPhysicalTableTypes();
488+
if (extraPhysicalTableTypes != null && !extraPhysicalTableTypes.isEmpty()) {
489+
String extraTableTypesStr = String.join(",", extraPhysicalTableTypes);
490+
runtimeSettingsBuilder.put(AvailableSettings.EXTRA_PHYSICAL_TABLE_TYPES, extraTableTypesStr);
491+
}
492+
486493
runtimeSettingsBuilder.put(AvailableSettings.JAKARTA_HBM2DDL_DATABASE_ACTION,
487494
persistenceUnitConfig.database().generation().generation()
488495
.orElse(generationStrategy));

extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/HibernateOrmRuntimeConfigPersistenceUnit.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.quarkus.hibernate.orm.runtime;
22

3+
import java.util.List;
34
import java.util.Map;
45
import java.util.Optional;
56

@@ -172,6 +173,20 @@ interface HibernateOrmConfigPersistenceUnitSchemaManagement {
172173
*/
173174
@WithDefault("false")
174175
boolean haltOnError();
176+
177+
/**
178+
* Additional database object types to include in schema management operations.
179+
*
180+
* By default, Hibernate ORM only considers tables and sequences when performing
181+
* schema management operations.
182+
* This setting allows you to specify additional database object types that should be included,
183+
* such as "MATERIALIZED VIEW", "VIEW", or other database-specific object types.
184+
*
185+
* The exact supported values depend on the underlying database and dialect.
186+
*
187+
* @asciidoclet
188+
*/
189+
List<@WithConverter(TrimmedStringConverter.class) String> extraPhysicalTableTypes();
175190
}
176191

177192
@ConfigGroup

extensions/hibernate-reactive/runtime/src/main/java/io/quarkus/hibernate/reactive/runtime/FastBootHibernateReactivePersistenceProvider.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,13 @@ private static void injectRuntimeConfiguration(HibernateOrmRuntimeConfigPersiste
383383
"When using offline mode with `quarkus.hibernate-orm.database.start-offline=true`, the schema management strategy `quarkus.hibernate-orm.schema-management.strategy` must be unset or set to `none`");
384384
}
385385

386+
// Pass extraPhysicalTableTypes configuration
387+
List<String> extraPhysicalTableTypes = persistenceUnitConfig.schemaManagement().extraPhysicalTableTypes();
388+
if (extraPhysicalTableTypes != null && !extraPhysicalTableTypes.isEmpty()) {
389+
String extraTableTypesStr = String.join(",", extraPhysicalTableTypes);
390+
runtimeSettingsBuilder.put(AvailableSettings.EXTRA_PHYSICAL_TABLE_TYPES, extraTableTypesStr);
391+
}
392+
386393
// Database
387394
runtimeSettingsBuilder.put(AvailableSettings.JAKARTA_HBM2DDL_DATABASE_ACTION,
388395
persistenceUnitConfig.database().generation().generation()

extensions/kubernetes-client/deployment/src/main/java/io/quarkus/kubernetes/client/deployment/DevServicesKubernetesProcessor.java

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,8 @@ public void applyManifests(
184184
KubernetesDevServiceInfoBuildItem kubernetesDevServiceInfoBuildItem,
185185
KubernetesClientBuildConfig kubernetesClientBuildTimeConfig) {
186186
if (kubernetesDevServiceInfoBuildItem == null) {
187-
// Gracefully return in case the Kubernetes dev service could not be spun up.
188-
log.warn("Cannot apply manifests because the Kubernetes dev service is not running");
187+
// Gracefully return in case the Kubernetes dev service could not be found
188+
log.error("Cannot apply manifests because the Kubernetes dev service is not running");
189189
return;
190190
}
191191

@@ -367,6 +367,13 @@ private RunningDevService startKubernetes(DockerStatusBuildItem dockerStatusBuil
367367
getKubernetesClientConfigFromKubeConfig(kubeConfig));
368368
};
369369

370+
maybeContainerAddress.ifPresent(containerAddress -> {
371+
devServicesKube
372+
.produce(new KubernetesDevServiceInfoBuildItem(
373+
KubeConfigUtils.serializeKubeConfig(getKubeconfigFromRunningContainer(containerAddress)),
374+
containerAddress.getId()));
375+
});
376+
370377
return maybeContainerAddress
371378
.map(containerAddress -> new RunningDevService(Feature.KUBERNETES_CLIENT.getName(),
372379
containerAddress.getId(),
@@ -425,6 +432,13 @@ private Map<String, String> resolveConfigurationFromRunningContainer(ContainerAd
425432
return container.getKubeconfig();
426433
}
427434

435+
private KubeConfig getKubeconfigFromRunningContainer(ContainerAddress containerAddress) {
436+
var dockerClient = DockerClientFactory.lazyClient();
437+
var container = new RunningContainer(dockerClient, containerAddress);
438+
439+
return container.getKubeconfigFromContainer();
440+
}
441+
428442
private KubernetesDevServiceCfg getConfiguration(KubernetesClientBuildConfig cfg) {
429443
KubernetesDevServicesBuildTimeConfig devServicesConfig = cfg.devservices();
430444
return new KubernetesDevServiceCfg(devServicesConfig);
@@ -496,19 +510,19 @@ public RunningContainer(DockerClient dockerClient, ContainerAddress containerAdd
496510
this.containerInfo = dockerClient.inspectContainerCmd(getContainerId()).exec();
497511
}
498512

499-
public Map<String, String> getKubeconfig() {
513+
private KubeConfig getKubeconfigFromContainer() {
500514
var image = getContainerInfo().getConfig().getImage();
501515
if (image.contains("rancher/k3s")) {
502-
return getKubernetesClientConfigFromKubeConfig(
503-
KubeConfigUtils.parseKubeConfig(KubeConfigUtils.replaceServerInKubeconfig(containerAddress.getUrl(),
504-
getFileContentFromContainer(K3S_KUBECONFIG))));
516+
return KubeConfigUtils
517+
.parseKubeConfig(KubeConfigUtils.replaceServerInKubeconfig("https://" + containerAddress.getUrl(),
518+
getFileContentFromContainer(K3S_KUBECONFIG)));
505519
} else if (image.contains("kindest/node")) {
506-
return getKubernetesClientConfigFromKubeConfig(
507-
KubeConfigUtils.parseKubeConfig(KubeConfigUtils.replaceServerInKubeconfig(containerAddress.getUrl(),
508-
getFileContentFromContainer(KIND_KUBECONFIG))));
520+
return KubeConfigUtils
521+
.parseKubeConfig(KubeConfigUtils.replaceServerInKubeconfig("https://" + containerAddress.getUrl(),
522+
getFileContentFromContainer(KIND_KUBECONFIG)));
509523
} else if (image.contains("k8s.gcr.io/kube-apiserver") ||
510524
image.contains("registry.k8s.io/kube-apiserver")) {
511-
return getKubernetesClientConfigFromKubeConfig(getKubeconfigFromApiContainer(containerAddress.getUrl()));
525+
return getKubeconfigFromApiContainer(containerAddress.getUrl());
512526
}
513527

514528
// this can happen only if the user manually start
@@ -517,6 +531,10 @@ public Map<String, String> getKubeconfig() {
517531
+ "' is not compatible with Dev Services for Kubernetes. Stop it or disable Dev Services for Kubernetes.");
518532
}
519533

534+
public Map<String, String> getKubeconfig() {
535+
return getKubernetesClientConfigFromKubeConfig(getKubeconfigFromContainer());
536+
}
537+
520538
protected KubeConfig getKubeconfigFromApiContainer(final String url) {
521539
final Cluster cluster = new Cluster();
522540
cluster.setName(APISERVER);

0 commit comments

Comments
 (0)