|
5 | 5 | package org.hibernate.type; |
6 | 6 |
|
7 | 7 | import java.io.Serializable; |
| 8 | +import java.util.ArrayList; |
| 9 | +import java.util.List; |
8 | 10 | import java.util.Map; |
9 | 11 | import java.util.concurrent.ConcurrentHashMap; |
10 | 12 | import java.util.function.Supplier; |
@@ -49,6 +51,7 @@ public class BasicTypeRegistry implements Serializable { |
49 | 51 |
|
50 | 52 | private final Map<String, BasicType<?>> typesByName = new ConcurrentHashMap<>(); |
51 | 53 | private final Map<String, BasicTypeReference<?>> typeReferencesByName = new ConcurrentHashMap<>(); |
| 54 | + private final Map<String, List<BasicTypeReference<?>>> typeReferencesByJavaTypeName = new ConcurrentHashMap<>(); |
52 | 55 |
|
53 | 56 | public BasicTypeRegistry(TypeConfiguration typeConfiguration){ |
54 | 57 | this.typeConfiguration = typeConfiguration; |
@@ -256,11 +259,25 @@ private <J> BasicType<J> createIfUnregistered( |
256 | 259 | if ( registeredTypeMatches( javaType, jdbcType, registeredType ) ) { |
257 | 260 | return castNonNull( registeredType ); |
258 | 261 | } |
259 | | - else { |
260 | | - final var createdType = creator.get(); |
261 | | - register( javaType, jdbcType, createdType ); |
262 | | - return createdType; |
| 262 | + // Create an ad-hoc type since the java type doesn't come from the registry and is probably explicitly defined |
| 263 | + else if ( typeConfiguration.getJavaTypeRegistry().resolveDescriptor( javaType.getJavaType() ) == javaType ) { |
| 264 | + final var basicTypeReferences = typeReferencesByJavaTypeName.get( javaType.getTypeName() ); |
| 265 | + if ( basicTypeReferences != null && !basicTypeReferences.isEmpty() ) { |
| 266 | + final var jdbcTypeRegistry = typeConfiguration.getJdbcTypeRegistry(); |
| 267 | + for ( var typeReference : basicTypeReferences ) { |
| 268 | + if ( jdbcTypeRegistry.getDescriptor( typeReference.getSqlTypeCode() ) == jdbcType ) { |
| 269 | + final var basicType = typesByName.get( typeReference.getName() ); |
| 270 | + //noinspection unchecked |
| 271 | + return basicType != null |
| 272 | + ? (BasicType<J>) basicType |
| 273 | + : (BasicType<J>) createBasicType( typeReference.getName(), typeReference ); |
| 274 | + } |
| 275 | + } |
| 276 | + } |
263 | 277 | } |
| 278 | + final var createdType = creator.get(); |
| 279 | + register( javaType, jdbcType, createdType ); |
| 280 | + return createdType; |
264 | 281 | } |
265 | 282 |
|
266 | 283 | private static <J> boolean registeredTypeMatches(JavaType<J> javaType, JdbcType jdbcType, BasicType<J> registeredType) { |
@@ -334,7 +351,7 @@ public void addTypeReferenceRegistrationKey(String typeReferenceKey, String... a |
334 | 351 | throw new IllegalArgumentException( "Couldn't find type reference with name: " + typeReferenceKey ); |
335 | 352 | } |
336 | 353 | for ( String additionalTypeReferenceKey : additionalTypeReferenceKeys ) { |
337 | | - typeReferencesByName.put( additionalTypeReferenceKey, basicTypeReference ); |
| 354 | + addTypeReference( additionalTypeReferenceKey, basicTypeReference ); |
338 | 355 | } |
339 | 356 | } |
340 | 357 |
|
@@ -384,7 +401,7 @@ public void addPrimeEntry(BasicTypeReference<?> type, String legacyTypeClassName |
384 | 401 |
|
385 | 402 | // Legacy name registration |
386 | 403 | if ( isNotEmpty( legacyTypeClassName ) ) { |
387 | | - typeReferencesByName.put( legacyTypeClassName, type ); |
| 404 | + addTypeReference( legacyTypeClassName, type ); |
388 | 405 | } |
389 | 406 |
|
390 | 407 | // explicit registration keys |
@@ -429,19 +446,31 @@ private void applyRegistrationKeys(BasicTypeReference<?> type, String[] keys) { |
429 | 446 | // Incidentally, this might also help with map lookup efficiency. |
430 | 447 | key = key.intern(); |
431 | 448 |
|
432 | | - // Incredibly verbose logging disabled |
433 | | -// LOG.tracef( "Adding type registration %s -> %s", key, type ); |
| 449 | + addTypeReference( key, type ); |
| 450 | + } |
| 451 | + } |
| 452 | + } |
| 453 | + |
| 454 | + private void addTypeReference(String name, BasicTypeReference<?> typeReference) { |
| 455 | + // Incredibly verbose logging disabled |
| 456 | +// LOG.tracef( "Adding type registration %s -> %s", key, type ); |
434 | 457 |
|
435 | 458 | // final BasicTypeReference<?> old = |
436 | | - typeReferencesByName.put( key, type ); |
437 | | -// if ( old != null && old != type ) { |
438 | | -// LOG.tracef( |
439 | | -// "Type registration key [%s] overrode previous entry : `%s`", |
440 | | -// key, |
441 | | -// old |
442 | | -// ); |
443 | | -// } |
444 | | - } |
| 459 | + typeReferencesByName.put( name, typeReference ); |
| 460 | +// if ( old != null && old != type ) { |
| 461 | +// LOG.tracef( |
| 462 | +// "Type registration key [%s] overrode previous entry : `%s`", |
| 463 | +// key, |
| 464 | +// old |
| 465 | +// ); |
| 466 | +// } |
| 467 | + |
| 468 | + final var basicTypeReferences = typeReferencesByJavaTypeName.computeIfAbsent( |
| 469 | + typeReference.getJavaType().getTypeName(), |
| 470 | + s -> new ArrayList<>() |
| 471 | + ); |
| 472 | + if ( !basicTypeReferences.contains( typeReference ) ) { |
| 473 | + basicTypeReferences.add( typeReference ); |
445 | 474 | } |
446 | 475 | } |
447 | 476 | } |
0 commit comments