Introduce a SqlFunctionContributor

Description

Introduce a SqlFunctionContributor for the ability to augment the SqlFunctionRegistry

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

Karel Maesen

Reporter

Components

Fix versions

Priority

Created June 28, 2016 at 5:41 PM
Updated October 28, 2021 at 12:41 PM
Resolved October 28, 2021 at 12:41 PM