Introduce a SqlFunctionContributor
Description
Activity
Show:
Christian Beikov October 28, 2021 at 12:41 PM
This was fixed already. The contract is called org.hibernate.boot.model.FunctionContributor
Steve Ebersole November 23, 2019 at 2:27 PM
After the work between Alpha2 and Alpha3 wrt the type system this is a bit out of sync at the moment. But moving forward with it based on the Alpha3 changes is dependent on a PR we’ve been waiting to get integrated.
Steve Ebersole February 15, 2018 at 8:00 PM
This is actually done already... For the most part... 6.0 is still evolving, but i feel pretty comfortable with the solution we have.
We'd be happy to have more eyes on that code and any feedback..
Martin Frey February 15, 2018 at 7:44 PM
I just did something like this based on the MetadataBuilderInitializer. Probably it helps 🙂 (Just ignore the Spring stuff)
It would be nice to get access to the SQLFunctionRegistry via the ServiceLocator.
public interface HibernateSqlFunctionRegistrar {
default void registerFunction(Map<String, SQLFunction> sqlFunctions, String name, SQLFunction function) {
// HHH-7721: SQLFunctionRegistry expects all lowercase. Enforce,
// just in case a user's customer dialect uses mixed cases.
sqlFunctions.put(name.toLowerCase(Locale.ROOT), function);
}
Map<String, SQLFunction> getSqlFunctions(Dialect dialect);
}
public class HibernateSpringIntegrator
implements MetadataBuilderInitializer, ApplicationContextAware {
private static ApplicationContext applicationContext;
/** The Constant log. */
private static final Logger log = LoggerFactory.getLogger(HibernateSpringIntegrator.class);
@Override
public void contribute(final MetadataBuilder metadataBuilder, final StandardServiceRegistry serviceRegistry) {
log.info("Registering custom SQL functions"); //$NON-NLS-1$
try {
Map<String, HibernateSqlFunctionRegistrar> registars =
HibernateSpringIntegrator.applicationContext.getBeansOfType(HibernateSqlFunctionRegistrar.class);
String dialectClassname =
HibernateSpringIntegrator.applicationContext.getBean("jpaProperties", Properties.class)
.getProperty("hibernate.dialect");
Dialect dialect = (Dialect) Class.forName(dialectClassname).newInstance();
registars.forEach((beanname, registrar) -> {
Class<?> listenerClass = AopUtils.getTargetClass(registrar);
log.debug("Registering: {}", listenerClass); //$NON-NLS-1$
registrar.getSqlFunctions(dialect).forEach((name, sqlFunction) -> {
metadataBuilder.applySqlFunction(name, sqlFunction);
});
});
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
public class GCOSqlFunctionRegistrar implements HibernateSqlFunctionRegistrar {
@Override
public Map<String, SQLFunction> getSqlFunctions(Dialect dialect) {
Map<String, SQLFunction> sqlFunctions = new HashMap<>();
if (dialect instanceof HSQLDialect) {
registerFunction(sqlFunctions, "get_action_status",
new StandardSQLFunction("get_action_status", StandardBasicTypes.STRING));
} else if (dialect instanceof Oracle12cDialect) {
registerFunction(sqlFunctions, "get_action_status",
new StandardSQLFunction("somepkg.get_action_status", StandardBasicTypes.STRING));
}
return sqlFunctions;
}
}
Fixed
Details
Assignee
Reporter
Steve Ebersole
Steve EbersoleLabels
Components
Fix versions
Priority
Major
Created June 28, 2016 at 5:41 PM
Updated October 28, 2021 at 12:41 PM
Resolved October 28, 2021 at 12:41 PM
Introduce a SqlFunctionContributor for the ability to augment the SqlFunctionRegistry