[hibernate-dev] Backport caching ValueBinders and ValueExtractors for a SqlTypeDescriptor from 6.0 to 5.x

Steve Ebersole steve at hibernate.org
Tue Jun 19 09:36:08 EDT 2018

Today, when either `SqlTypeDescriptor#getBinder` or
`SqlTypeDescriptor#getExtractor` are called we build/calculate the
binder/extractor each and every time.  In 6.0 we added code that caches
these binders and extractors as they are requested.

IMO we should backport the idea of caching these to 5.x.  Any volunteers?

The code on 6.0 is still local to my machine, but the code in general looks

public interface SqlTypeDescriptor {

<X>JdbcValueMapper<X> getJdbcValueMapper(BasicJavaDescriptor<X>

default <X> JdbcValueBinder<X> getBinder(BasicJavaDescriptor<X>
javaTypeDescriptor) {
return getJdbcValueMapper( javaTypeDescriptor ).getJdbcValueBinder();

default <X> JdbcValueExtractor<X> getExtractor(BasicJavaDescriptor<X>
javaTypeDescriptor) {
return getJdbcValueMapper( javaTypeDescriptor ).getJdbcValueExtractor();

public abstract class AbstractSqlTypeDescriptor implements
SqlTypeDescriptor {
private final Map<JavaTypeDescriptor<?>,JdbcValueMapper<?>>
valueMapperCache = new ConcurrentHashMap<>();

protected <J> JdbcValueMapper<J> determineValueMapper(
JavaTypeDescriptor<J> javaTypeDescriptor,
Function<JavaTypeDescriptor<J>,JdbcValueMapper<J>> creator) {
return (JdbcValueMapper<J>) valueMapperCache.computeIfAbsent(
javaTypeDescriptor1 -> creator.apply( javaTypeDescriptor )

public abstract class AbstractTemplateSqlTypeDescriptor extends
AbstractSqlTypeDescriptor {
public <X> JdbcValueMapper<X> getJdbcValueMapper(BasicJavaDescriptor<X>
javaTypeDescriptor) {
return determineValueMapper(
jtd -> {
final JdbcValueBinder<X> binder = createBinder( javaTypeDescriptor );
final JdbcValueExtractor<X> extractor = createExtractor( javaTypeDescriptor

return new JdbcValueMapperImpl<>( javaTypeDescriptor, this, extractor,
binder );

protected abstract <X> JdbcValueBinder<X>
createBinder(BasicJavaDescriptor<X> javaTypeDescriptor);

protected abstract <X> JdbcValueExtractor<X>
createExtractor(BasicJavaDescriptor<X> javaTypeDescriptor);

[1] In 6.0 ValueBinder is replaced by JdbcValueBinder and ValueExtractor is
replaced by JdbcValueExtractor - the new variants serve the same basic
purposes but in different ways related to the other changes  in 6.0.
JdbcValueMapper is a new contract that combines a JavaTypeDescriptor
(specifically a BasicJavaDescriptor since all JDBC types are "basic"),
SqlTypeDescriptor, JdbcValueBinder and JdbcValueExtractor

More information about the hibernate-dev mailing list