Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ public static void bindDefaults(MetadataBuildingContext context) {
QueryBinder.bindNamedStoredProcedureQuery( queryRegistration.configuration(), context, true );
} );

globalRegistrations.getDatabaseObjectRegistrations().forEach( databaseObjectRegistration ->
AuxiliaryDatabaseObjectBinder.processAuxiliaryDatabaseObject( context, databaseObjectRegistration )
);

}

private static ModelsContext modelsContext(MetadataBuildingContext context) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.boot.model.internal;

import org.hibernate.MappingException;
import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject;
import org.hibernate.boot.model.relational.SimpleAuxiliaryDatabaseObject;
import org.hibernate.boot.models.spi.DatabaseObjectRegistration;
import org.hibernate.boot.models.spi.DialectScopeRegistration;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.models.internal.util.StringHelper;

public class AuxiliaryDatabaseObjectBinder {
public static void processAuxiliaryDatabaseObject(
MetadataBuildingContext context,
DatabaseObjectRegistration databaseObjectRegistration) {
final AuxiliaryDatabaseObject auxDbObject;

if ( StringHelper.isNotEmpty( databaseObjectRegistration.definition()) ) {
try {
auxDbObject = (AuxiliaryDatabaseObject)
context.getBootstrapContext().getClassLoaderService()
.classForName( databaseObjectRegistration.definition() )
.newInstance();
Comment on lines +25 to +27

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note

Invoking
Class.newInstance
should be avoided because it has been deprecated.
}
catch (ClassLoadingException cle) {
throw cle;
}
catch (Exception e) {
throw new MappingException(
String.format(
"Unable to instantiate custom AuxiliaryDatabaseObject class [%s]",
databaseObjectRegistration.definition()
)
);
}
}
else {
auxDbObject = new SimpleAuxiliaryDatabaseObject(
context.getMetadataCollector().getDatabase().getDefaultNamespace(),
databaseObjectRegistration.create(),
databaseObjectRegistration.drop(),
null
);
}

if ( !databaseObjectRegistration.dialectScopes().isEmpty() ) {
if ( auxDbObject instanceof AuxiliaryDatabaseObject.Expandable expandable ) {
for ( DialectScopeRegistration dialectScopeRegistration : databaseObjectRegistration.dialectScopes() ) {
expandable.addDialectScope( dialectScopeRegistration.name());
}
}
else {
// error? warn?
}
}

context.getMetadataCollector().getDatabase().addAuxiliaryDatabaseObject( auxDbObject );
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ public void apply(JaxbEntityMappingsImpl jaxbRoot, XmlDocumentContext xmlDocumen

getGlobalRegistrations().collectQueryReferences( jaxbRoot, xmlDocumentContext );

getGlobalRegistrations().collectDataBaseObject( jaxbRoot.getDatabaseObjects() );
// todo (7.0) : named graphs?
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import org.hibernate.boot.jaxb.mapping.spi.JaxbConfigurationParameterImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbConverterImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbConverterRegistrationImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbDatabaseObjectImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbDatabaseObjectScopeImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddableInstantiatorRegistrationImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListenerImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
Expand Down Expand Up @@ -53,6 +55,8 @@
import org.hibernate.boot.models.spi.CompositeUserTypeRegistration;
import org.hibernate.boot.models.spi.ConversionRegistration;
import org.hibernate.boot.models.spi.ConverterRegistration;
import org.hibernate.boot.models.spi.DatabaseObjectRegistration;
import org.hibernate.boot.models.spi.DialectScopeRegistration;
import org.hibernate.boot.models.spi.EmbeddableInstantiatorRegistration;
import org.hibernate.boot.models.spi.FilterDefRegistration;
import org.hibernate.boot.models.spi.GenericGeneratorRegistration;
Expand Down Expand Up @@ -144,6 +148,8 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations, GlobalRegis
private Map<String, NamedNativeQueryRegistration> namedNativeQueryRegistrations;
private Map<String, NamedStoredProcedureQueryRegistration> namedStoredProcedureQueryRegistrations;

private List<DatabaseObjectRegistration> databaseObjectRegistrations;

public GlobalRegistrationsImpl(ModelsContext sourceModelContext, BootstrapContext bootstrapContext) {
this.sourceModelContext = sourceModelContext;
this.bootstrapContext = bootstrapContext;
Expand Down Expand Up @@ -242,9 +248,13 @@ public Map<String, NamedNativeQueryRegistration> getNamedNativeQueryRegistration

@Override
public Map<String, NamedStoredProcedureQueryRegistration> getNamedStoredProcedureQueryRegistrations() {
return namedStoredProcedureQueryRegistrations== null ? emptyMap() : namedStoredProcedureQueryRegistrations;
return namedStoredProcedureQueryRegistrations == null ? emptyMap() : namedStoredProcedureQueryRegistrations;
}

@Override
public List<DatabaseObjectRegistration> getDatabaseObjectRegistrations() {
return databaseObjectRegistrations == null ? emptyList() : databaseObjectRegistrations;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JavaTypeRegistration
Expand Down Expand Up @@ -1314,4 +1324,34 @@ private List<QueryHint> extractQueryHints(JaxbQueryHintContainer jaxbQuery) {
}
return hints;
}

public void collectDataBaseObject(List<JaxbDatabaseObjectImpl> databaseObjects) {
if ( isEmpty( databaseObjects ) ) {
return;
}

if ( databaseObjectRegistrations == null ) {
databaseObjectRegistrations = new ArrayList<>();
}

for ( JaxbDatabaseObjectImpl jaxbDatabaseObject : databaseObjects ) {
final JaxbDatabaseObjectImpl.JaxbDefinitionImpl definition = jaxbDatabaseObject.getDefinition();
final List<JaxbDatabaseObjectScopeImpl> dialectScopes = jaxbDatabaseObject.getDialectScopes();
final List<DialectScopeRegistration> scopeRegistrations = new ArrayList<>(dialectScopes.size());
for ( JaxbDatabaseObjectScopeImpl dialectScope : dialectScopes ) {
scopeRegistrations.add(
new DialectScopeRegistration(
dialectScope.getName(),
dialectScope.getContent(),
dialectScope.getMinimumVersion(),
dialectScope.getMaximumVersion() )
);
}
databaseObjectRegistrations.add( new DatabaseObjectRegistration(
jaxbDatabaseObject.getCreate(),
jaxbDatabaseObject.getDrop(),
definition != null ? definition.getClazz() : null,
scopeRegistrations ) );
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.boot.models.spi;

import java.util.List;

public record DatabaseObjectRegistration(String create, String drop, String definition, List<DialectScopeRegistration> dialectScopes ) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.boot.models.spi;

public record DialectScopeRegistration(String name, String content, String minimumVersion, String maximumVersion) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public interface GlobalRegistrations {

Map<String, NamedStoredProcedureQueryRegistration> getNamedStoredProcedureQueryRegistrations();

List<DatabaseObjectRegistration> getDatabaseObjectRegistrations();

// todo : named entity graphs

<T> T as(Class<T> type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@
metadataSources.addInputStream( getClass().getResourceAsStream( "implicit-file-level-catalog-and-schema.hbm.xml" ) );
metadataSources.addInputStream( getClass().getResourceAsStream( "no-file-level-catalog-and-schema.orm.xml" ) );
metadataSources.addInputStream( getClass().getResourceAsStream( "no-file-level-catalog-and-schema.hbm.xml" ) );
metadataSources.addInputStream( getClass().getResourceAsStream( "database-object-using-catalog-placeholder.hbm.xml" ) );
metadataSources.addInputStream( getClass().getResourceAsStream( "database-object-using-schema-placeholder.hbm.xml" ) );
metadataSources.addInputStream( getClass().getResourceAsStream( "database-object-using-catalog-placeholder.orm.xml" ) );

Check warning

Code scanning / CodeQL

Unsafe use of getResource Warning test

The idiom getClass().getResource() is unsafe for classes that may be extended.
metadataSources.addInputStream( getClass().getResourceAsStream( "database-object-using-schema-placeholder.orm.xml" ) );

Check warning

Code scanning / CodeQL

Unsafe use of getResource Warning test

The idiom getClass().getResource() is unsafe for classes that may be extended.
if ( configuredXmlMappingPath != null ) {
metadataSources.addInputStream( getClass().getResourceAsStream( configuredXmlMappingPath ) );
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ SPDX-License-Identifier: Apache-2.0
~ Copyright Red Hat Inc. and Hibernate Authors
-->
<entity-mappings xmlns="http://www.hibernate.org/xsd/orm/mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="7.0">
<database-object>
<!-- Note this code does not actually get executed.
We just generate the script and check that ${catalog} gets replaced correctly.
So the actual language used here does not need to be compatible with the DB dialect under test.
-->
<create>
CREATE OR REPLACE FUNCTION ${catalog}.catalogPrefixedAuxObject()
RETURNS varchar AS
$BODY$
BEGIN
SELECT 'test';
END;
$BODY$
LANGUAGE plpgsql
</create>
<drop>DROP FUNCTION ${catalog}.catalogPrefixedAuxObject()</drop>
</database-object>
</entity-mappings>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ SPDX-License-Identifier: Apache-2.0
~ Copyright Red Hat Inc. and Hibernate Authors
-->
<entity-mappings xmlns="http://www.hibernate.org/xsd/orm/mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="7.0">
<database-object>
<!-- Note this code does not actually get executed.
We just generate the script and check that ${schema} gets replaced correctly.
So the actual language used here does not need to be compatible with the DB dialect under test.
-->
<create>
CREATE OR REPLACE FUNCTION ${schema}.schemaPrefixedAuxObject()
RETURNS varchar AS
$BODY$
BEGIN
SELECT 'test';
END;
$BODY$
LANGUAGE plpgsql
</create>
<drop>DROP FUNCTION ${schema}.schemaPrefixedAuxObject()</drop>

</database-object>
</entity-mappings>