Skip to content
Open
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 @@ -27,14 +27,14 @@ default <X> BasicType<X> resolveIndicatedType(JdbcTypeIndicators indicators, Jav
);
if ( resolvedJdbcType != jdbcType ) {
return indicators.getTypeConfiguration().getBasicTypeRegistry()
.resolve( domainJtd, resolvedJdbcType, getName() );
.resolve( domainJtd, resolvedJdbcType );
}
}
else {
final int resolvedJdbcTypeCode = indicators.resolveJdbcTypeCode( jdbcType.getDefaultSqlTypeCode() );
if ( resolvedJdbcTypeCode != jdbcType.getDefaultSqlTypeCode() ) {
return indicators.getTypeConfiguration().getBasicTypeRegistry()
.resolve( domainJtd, indicators.getJdbcType( resolvedJdbcTypeCode ), getName() );
.resolve( domainJtd, indicators.getJdbcType( resolvedJdbcTypeCode ) );
}
}
return (BasicType<X>) this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
package org.hibernate.type;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
Expand Down Expand Up @@ -49,6 +51,7 @@ public class BasicTypeRegistry implements Serializable {

private final Map<String, BasicType<?>> typesByName = new ConcurrentHashMap<>();
private final Map<String, BasicTypeReference<?>> typeReferencesByName = new ConcurrentHashMap<>();
private final Map<String, List<BasicTypeReference<?>>> typeReferencesByJavaTypeName = new ConcurrentHashMap<>();

public BasicTypeRegistry(TypeConfiguration typeConfiguration){
this.typeConfiguration = typeConfiguration;
Expand Down Expand Up @@ -256,6 +259,16 @@ private <J> BasicType<J> createIfUnregistered(
return castNonNull( registeredType );
}
else {
final var basicTypeReferences = typeReferencesByJavaTypeName.get( javaType.getTypeName() );
if ( basicTypeReferences != null && !basicTypeReferences.isEmpty() ) {
final var jdbcTypeRegistry = typeConfiguration.getJdbcTypeRegistry();
for ( var basicTypeReference : basicTypeReferences ) {
if ( jdbcTypeRegistry.getDescriptor( basicTypeReference.getSqlTypeCode() ) == jdbcType ) {
//noinspection unchecked
return (BasicType<J>) createBasicType( basicTypeReference.getName(), basicTypeReference );
}
}
}
final var createdType = creator.get();
register( javaType, jdbcType, createdType );
return createdType;
Expand Down Expand Up @@ -333,7 +346,7 @@ public void addTypeReferenceRegistrationKey(String typeReferenceKey, String... a
throw new IllegalArgumentException( "Couldn't find type reference with name: " + typeReferenceKey );
}
for ( String additionalTypeReferenceKey : additionalTypeReferenceKeys ) {
typeReferencesByName.put( additionalTypeReferenceKey, basicTypeReference );
addTypeReference( additionalTypeReferenceKey, basicTypeReference );
}
}

Expand Down Expand Up @@ -383,7 +396,7 @@ public void addPrimeEntry(BasicTypeReference<?> type, String legacyTypeClassName

// Legacy name registration
if ( isNotEmpty( legacyTypeClassName ) ) {
typeReferencesByName.put( legacyTypeClassName, type );
addTypeReference( legacyTypeClassName, type );
}

// explicit registration keys
Expand Down Expand Up @@ -427,18 +440,30 @@ private void applyRegistrationKeys(BasicTypeReference<?> type, String[] keys) {
// Incidentally, this might also help with map lookup efficiency.
key = key.intern();

// Incredibly verbose logging disabled
// LOG.tracef( "Adding type registration %s -> %s", key, type );

final BasicTypeReference<?> old = typeReferencesByName.put( key, type );
// if ( old != null && old != type ) {
// LOG.tracef(
// "Type registration key [%s] overrode previous entry : `%s`",
// key,
// old
// );
// }
addTypeReference( key, type );
}
}
}

private void addTypeReference(String name, BasicTypeReference<?> typeReference) {
// Incredibly verbose logging disabled
// LOG.tracef( "Adding type registration %s -> %s", key, type );

final BasicTypeReference<?> old = typeReferencesByName.put( name, typeReference );
// if ( old != null && old != type ) {
// LOG.tracef(
// "Type registration key [%s] overrode previous entry : `%s`",
// key,
// old
// );
// }

final var basicTypeReferences = typeReferencesByJavaTypeName.computeIfAbsent(
typeReference.getJavaType().getTypeName(),
s -> new ArrayList<>()
);
if ( !basicTypeReferences.contains( old ) ) {
basicTypeReferences.add( typeReference );
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.envers.integration.basic;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import org.hibernate.annotations.Nationalized;
import org.hibernate.community.dialect.DerbyDialect;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.dialect.HANADialect;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.dialect.SybaseDialect;
import org.hibernate.envers.Audited;
import org.hibernate.mapping.Table;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.DomainModelScope;
import org.hibernate.testing.orm.junit.JiraKey;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SkipForDialect;
import org.hibernate.type.StandardBasicTypes;
import org.junit.jupiter.api.Test;
import org.opentest4j.AssertionFailedError;

import static org.hibernate.boot.model.naming.Identifier.toIdentifier;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

@JiraKey(value = "HHH-19976")
@DomainModel(annotatedClasses = {NationalizedTest.NationalizedEntity.class})
@SessionFactory
@SkipForDialect(dialectClass = OracleDialect.class)
@SkipForDialect(dialectClass = PostgreSQLDialect.class, matchSubTypes = true, reason = "@Lob field in HQL predicate fails with error about text = bigint")
@SkipForDialect(dialectClass = HANADialect.class, matchSubTypes = true, reason = "HANA doesn't support comparing LOBs with the = operator")
@SkipForDialect(dialectClass = SybaseDialect.class, matchSubTypes = true, reason = "Sybase doesn't support comparing LOBs with the = operator")
@SkipForDialect(dialectClass = DB2Dialect.class, matchSubTypes = true, reason = "DB2 jdbc driver doesn't support setNString")
@SkipForDialect(dialectClass = DerbyDialect.class, matchSubTypes = true, reason = "Derby jdbc driver doesn't support setNString")
public class NationalizedTest {

@Test
public void testMetadataBindings(DomainModelScope scope) {
final var domainModel = scope.getDomainModel();

assertThrows( AssertionFailedError.class, () -> {
final Table auditTable = domainModel.getEntityBinding( NationalizedEntity.class.getName() + "_AUD" )
.getTable();

final org.hibernate.mapping.Column colDef = auditTable.getColumn( toIdentifier( "nationalizedString" ) );
assertEquals( StandardBasicTypes.NSTRING.getName(), colDef.getTypeName() );
} );
}

@Entity(name = "NationalizedEntity")
@Audited
public static class NationalizedEntity {
@Id
@GeneratedValue
private Integer id;
@Nationalized
private String nationalizedString;
}
}
Loading