HHH-16388 - Configuration setting for wrapper Byte[]/Character[] treatment
This commit is contained in:
parent
f209423797
commit
b5220ff929
|
@ -78,6 +78,7 @@ import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.service.spi.ServiceException;
|
import org.hibernate.service.spi.ServiceException;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
|
import org.hibernate.type.WrapperArrayHandling;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
import org.hibernate.usertype.UserType;
|
import org.hibernate.usertype.UserType;
|
||||||
|
|
||||||
|
@ -87,6 +88,8 @@ import jakarta.persistence.AttributeConverter;
|
||||||
import jakarta.persistence.ConstraintMode;
|
import jakarta.persistence.ConstraintMode;
|
||||||
import jakarta.persistence.SharedCacheMode;
|
import jakarta.persistence.SharedCacheMode;
|
||||||
|
|
||||||
|
import static org.hibernate.cfg.AvailableSettings.WRAPPER_ARRAY_HANDLING;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
@ -582,6 +585,7 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
||||||
private final MappingDefaultsImpl mappingDefaults;
|
private final MappingDefaultsImpl mappingDefaults;
|
||||||
private final IdentifierGeneratorFactory identifierGeneratorFactory;
|
private final IdentifierGeneratorFactory identifierGeneratorFactory;
|
||||||
private final TimeZoneStorageType defaultTimezoneStorage;
|
private final TimeZoneStorageType defaultTimezoneStorage;
|
||||||
|
private final WrapperArrayHandling wrapperArrayHandling;
|
||||||
|
|
||||||
// todo (6.0) : remove bootstrapContext property along with the deprecated methods
|
// todo (6.0) : remove bootstrapContext property along with the deprecated methods
|
||||||
private BootstrapContext bootstrapContext;
|
private BootstrapContext bootstrapContext;
|
||||||
|
@ -619,6 +623,7 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
||||||
this.mappingDefaults = new MappingDefaultsImpl( serviceRegistry );
|
this.mappingDefaults = new MappingDefaultsImpl( serviceRegistry );
|
||||||
|
|
||||||
this.defaultTimezoneStorage = resolveTimeZoneStorageStrategy( configService );
|
this.defaultTimezoneStorage = resolveTimeZoneStorageStrategy( configService );
|
||||||
|
this.wrapperArrayHandling = resolveWrapperArrayHandling( configService );
|
||||||
this.multiTenancyEnabled = JdbcEnvironmentImpl.isMultiTenancyEnabled( serviceRegistry );
|
this.multiTenancyEnabled = JdbcEnvironmentImpl.isMultiTenancyEnabled( serviceRegistry );
|
||||||
|
|
||||||
this.xmlMappingEnabled = configService.getSetting(
|
this.xmlMappingEnabled = configService.getSetting(
|
||||||
|
@ -868,6 +873,11 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WrapperArrayHandling getWrapperArrayHandling() {
|
||||||
|
return wrapperArrayHandling;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<BasicTypeRegistration> getBasicTypeRegistrations() {
|
public List<BasicTypeRegistration> getBasicTypeRegistrations() {
|
||||||
return basicTypeRegistrations;
|
return basicTypeRegistrations;
|
||||||
|
@ -999,4 +1009,21 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
||||||
TimeZoneStorageType.DEFAULT
|
TimeZoneStorageType.DEFAULT
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static WrapperArrayHandling resolveWrapperArrayHandling(
|
||||||
|
ConfigurationService configService) {
|
||||||
|
return configService.getSetting(
|
||||||
|
WRAPPER_ARRAY_HANDLING,
|
||||||
|
value -> {
|
||||||
|
if ( value == null ) {
|
||||||
|
throw new IllegalArgumentException( "Null value passed to convert" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return value instanceof WrapperArrayHandling
|
||||||
|
? (WrapperArrayHandling) value
|
||||||
|
: WrapperArrayHandling.valueOf( value.toString().toUpperCase( Locale.ROOT ) );
|
||||||
|
},
|
||||||
|
WrapperArrayHandling.DISALLOW
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,10 @@ import org.hibernate.mapping.Table;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.BasicTypeRegistry;
|
import org.hibernate.type.BasicTypeRegistry;
|
||||||
import org.hibernate.type.SqlTypes;
|
import org.hibernate.type.SqlTypes;
|
||||||
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
import org.hibernate.type.WrapperArrayHandling;
|
||||||
|
import org.hibernate.type.descriptor.java.ByteArrayJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.CharacterArrayJavaType;
|
||||||
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
|
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.JsonAsStringJdbcType;
|
import org.hibernate.type.descriptor.jdbc.JsonAsStringJdbcType;
|
||||||
|
@ -603,6 +607,21 @@ public class MetadataBuildingProcess {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if ( options.getWrapperArrayHandling() == WrapperArrayHandling.LEGACY ) {
|
||||||
|
typeConfiguration.getJavaTypeRegistry().addDescriptor( ByteArrayJavaType.INSTANCE );
|
||||||
|
typeConfiguration.getJavaTypeRegistry().addDescriptor( CharacterArrayJavaType.INSTANCE );
|
||||||
|
final BasicTypeRegistry basicTypeRegistry = typeConfiguration.getBasicTypeRegistry();
|
||||||
|
|
||||||
|
basicTypeRegistry.addTypeReferenceRegistrationKey(
|
||||||
|
StandardBasicTypes.CHARACTER_ARRAY.getName(),
|
||||||
|
Character[].class.getName(), "Character[]"
|
||||||
|
);
|
||||||
|
basicTypeRegistry.addTypeReferenceRegistrationKey(
|
||||||
|
StandardBasicTypes.BINARY_WRAPPER.getName(),
|
||||||
|
Byte[].class.getName(), "Byte[]"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// add Dialect contributed types
|
// add Dialect contributed types
|
||||||
final Dialect dialect = options.getServiceRegistry().getService( JdbcServices.class ).getDialect();
|
final Dialect dialect = options.getServiceRegistry().getService( JdbcServices.class ).getDialect();
|
||||||
dialect.contribute( typeContributions, options.getServiceRegistry() );
|
dialect.contribute( typeContributions, options.getServiceRegistry() );
|
||||||
|
|
|
@ -19,6 +19,7 @@ import org.hibernate.cache.spi.access.AccessType;
|
||||||
import org.hibernate.cfg.MetadataSourceType;
|
import org.hibernate.cfg.MetadataSourceType;
|
||||||
import org.hibernate.dialect.TimeZoneSupport;
|
import org.hibernate.dialect.TimeZoneSupport;
|
||||||
import org.hibernate.id.factory.IdentifierGeneratorFactory;
|
import org.hibernate.id.factory.IdentifierGeneratorFactory;
|
||||||
|
import org.hibernate.type.WrapperArrayHandling;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
import jakarta.persistence.SharedCacheMode;
|
import jakarta.persistence.SharedCacheMode;
|
||||||
|
@ -67,6 +68,11 @@ public abstract class AbstractDelegatingMetadataBuildingOptions implements Metad
|
||||||
return delegate.getTimeZoneSupport();
|
return delegate.getTimeZoneSupport();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WrapperArrayHandling getWrapperArrayHandling() {
|
||||||
|
return delegate.getWrapperArrayHandling();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<BasicTypeRegistration> getBasicTypeRegistrations() {
|
public List<BasicTypeRegistration> getBasicTypeRegistrations() {
|
||||||
return delegate.getBasicTypeRegistrations();
|
return delegate.getBasicTypeRegistrations();
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
|
||||||
import org.hibernate.id.factory.IdentifierGeneratorFactory;
|
import org.hibernate.id.factory.IdentifierGeneratorFactory;
|
||||||
import org.hibernate.metamodel.internal.ManagedTypeRepresentationResolverStandard;
|
import org.hibernate.metamodel.internal.ManagedTypeRepresentationResolverStandard;
|
||||||
import org.hibernate.metamodel.spi.ManagedTypeRepresentationResolver;
|
import org.hibernate.metamodel.spi.ManagedTypeRepresentationResolver;
|
||||||
|
import org.hibernate.type.WrapperArrayHandling;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
import jakarta.persistence.SharedCacheMode;
|
import jakarta.persistence.SharedCacheMode;
|
||||||
|
@ -70,6 +71,13 @@ public interface MetadataBuildingOptions {
|
||||||
*/
|
*/
|
||||||
TimeZoneSupport getTimeZoneSupport();
|
TimeZoneSupport getTimeZoneSupport();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the {@link WrapperArrayHandling} to use for wrapper arrays {@code Byte[]} and {@code Character[]}.
|
||||||
|
*
|
||||||
|
* @see org.hibernate.cfg.AvailableSettings#WRAPPER_ARRAY_HANDLING
|
||||||
|
*/
|
||||||
|
WrapperArrayHandling getWrapperArrayHandling();
|
||||||
|
|
||||||
default ManagedTypeRepresentationResolver getManagedTypeRepresentationResolver() {
|
default ManagedTypeRepresentationResolver getManagedTypeRepresentationResolver() {
|
||||||
// for now always return the standard one
|
// for now always return the standard one
|
||||||
return ManagedTypeRepresentationResolverStandard.INSTANCE;
|
return ManagedTypeRepresentationResolverStandard.INSTANCE;
|
||||||
|
|
|
@ -47,6 +47,7 @@ import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.CustomType;
|
import org.hibernate.type.CustomType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
import org.hibernate.type.WrapperArrayHandling;
|
||||||
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
|
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
|
||||||
import org.hibernate.type.descriptor.java.BasicJavaType;
|
import org.hibernate.type.descriptor.java.BasicJavaType;
|
||||||
import org.hibernate.type.descriptor.java.BasicPluralJavaType;
|
import org.hibernate.type.descriptor.java.BasicPluralJavaType;
|
||||||
|
@ -857,6 +858,18 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
|
||||||
return visitor.accept(this);
|
return visitor.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Internal
|
||||||
|
public boolean isDisallowedWrapperArray() {
|
||||||
|
return getBuildingContext().getBuildingOptions().getWrapperArrayHandling() == WrapperArrayHandling.DISALLOW
|
||||||
|
&& ( explicitJavaTypeAccess == null || explicitJavaTypeAccess.apply( getTypeConfiguration() ) == null )
|
||||||
|
&& isWrapperByteOrCharacterArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isWrapperByteOrCharacterArray() {
|
||||||
|
final Class<?> javaTypeClass = getResolution().getDomainJavaType().getJavaTypeClass();
|
||||||
|
return javaTypeClass == Byte[].class || javaTypeClass == Character[].class;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolved form of {@link BasicValue} as part of interpreting the
|
* Resolved form of {@link BasicValue} as part of interpreting the
|
||||||
* boot-time model into the run-time model
|
* boot-time model into the run-time model
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.hibernate.Internal;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.boot.model.relational.Database;
|
import org.hibernate.boot.model.relational.Database;
|
||||||
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper;
|
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.engine.spi.CascadeStyle;
|
import org.hibernate.engine.spi.CascadeStyle;
|
||||||
import org.hibernate.engine.spi.CascadeStyles;
|
import org.hibernate.engine.spi.CascadeStyles;
|
||||||
import org.hibernate.engine.spi.Mapping;
|
import org.hibernate.engine.spi.Mapping;
|
||||||
|
@ -33,6 +34,7 @@ import org.hibernate.generator.Generator;
|
||||||
import org.hibernate.generator.GeneratorCreationContext;
|
import org.hibernate.generator.GeneratorCreationContext;
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
import org.hibernate.type.WrapperArrayHandling;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A mapping model object representing a property or field of an {@linkplain PersistentClass entity}
|
* A mapping model object representing a property or field of an {@linkplain PersistentClass entity}
|
||||||
|
@ -282,7 +284,23 @@ public class Property implements Serializable, MetaAttributable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isValid(Mapping mapping) throws MappingException {
|
public boolean isValid(Mapping mapping) throws MappingException {
|
||||||
return getValue().isValid( mapping );
|
final Value value = getValue();
|
||||||
|
if ( value instanceof BasicValue && ( (BasicValue) value ).isDisallowedWrapperArray() ) {
|
||||||
|
throw new MappingException(
|
||||||
|
"The property " + persistentClass.getEntityName() + "#" + name +
|
||||||
|
" uses a wrapper type Byte[]/Character[] which indicates an issue in your domain model. " +
|
||||||
|
"These types have been treated like byte[]/char[] until Hibernate 6.2 which meant that " +
|
||||||
|
"null elements were not allowed, but on JDBC were processed like VARBINARY or VARCHAR. " +
|
||||||
|
"If you don't use nulls in your arrays, change the type of the property to byte[]/char[]. " +
|
||||||
|
"To allow explicit uses of the wrapper types Byte[]/Character[] which allows null element " +
|
||||||
|
"but has a different serialization format than before Hibernate 6.2, configure the " +
|
||||||
|
"setting " + AvailableSettings.WRAPPER_ARRAY_HANDLING + " to the value " + WrapperArrayHandling.ALLOW + ". " +
|
||||||
|
"To revert to the legacy treatment of these types, configure the value to " + WrapperArrayHandling.LEGACY + ". " +
|
||||||
|
"For more information on this matter, consult the migration guide of Hibernate 6.2 " +
|
||||||
|
"and the Javadoc of the org.hibernate.cfg.AvailableSettings.WRAPPER_ARRAY_HANDLING field."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return value.isValid( mapping );
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.Internal;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
@ -277,6 +278,17 @@ public class BasicTypeRegistry implements Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Internal
|
||||||
|
public void addTypeReferenceRegistrationKey(String typeReferenceKey, String... additionalTypeReferenceKeys) {
|
||||||
|
final BasicTypeReference<?> basicTypeReference = typeReferencesByName.get( typeReferenceKey );
|
||||||
|
if ( basicTypeReference == null ) {
|
||||||
|
throw new IllegalArgumentException( "Couldn't find type reference with name: " + typeReferenceKey );
|
||||||
|
}
|
||||||
|
for ( String additionalTypeReferenceKey : additionalTypeReferenceKeys ) {
|
||||||
|
typeReferencesByName.put( additionalTypeReferenceKey, basicTypeReference );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// priming
|
// priming
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.sql.Statement;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.dialect.OracleDialect;
|
import org.hibernate.dialect.OracleDialect;
|
||||||
import org.hibernate.dialect.PostgresPlusDialect;
|
import org.hibernate.dialect.PostgresPlusDialect;
|
||||||
|
@ -26,8 +27,10 @@ import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||||
import org.hibernate.testing.orm.junit.RequiresDialectFeatureGroup;
|
import org.hibernate.testing.orm.junit.RequiresDialectFeatureGroup;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
@ -48,6 +51,9 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
annotatedClasses = { SomeEntity.class, SomeOtherEntity.class }
|
annotatedClasses = { SomeEntity.class, SomeOtherEntity.class }
|
||||||
)
|
)
|
||||||
@SessionFactory
|
@SessionFactory
|
||||||
|
@ServiceRegistry(
|
||||||
|
settings = @Setting(name = AvailableSettings.WRAPPER_ARRAY_HANDLING, value = "ALLOW")
|
||||||
|
)
|
||||||
public class BasicOperationsTest {
|
public class BasicOperationsTest {
|
||||||
|
|
||||||
private static final String SOME_ENTITY_TABLE_NAME = "SOMEENTITY";
|
private static final String SOME_ENTITY_TABLE_NAME = "SOMEENTITY";
|
||||||
|
|
|
@ -9,8 +9,11 @@ package org.hibernate.orm.test.annotations.lob;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.dialect.SQLServerDialect;
|
import org.hibernate.dialect.SQLServerDialect;
|
||||||
import org.hibernate.dialect.SybaseDialect;
|
import org.hibernate.dialect.SybaseDialect;
|
||||||
|
import org.hibernate.type.WrapperArrayHandling;
|
||||||
|
|
||||||
import org.hibernate.testing.RequiresDialect;
|
import org.hibernate.testing.RequiresDialect;
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
@ -28,6 +31,12 @@ import junit.framework.AssertionFailedError;
|
||||||
public class ImageTest extends BaseCoreFunctionalTestCase {
|
public class ImageTest extends BaseCoreFunctionalTestCase {
|
||||||
private static final int ARRAY_SIZE = 10000;
|
private static final int ARRAY_SIZE = 10000;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(Configuration configuration) {
|
||||||
|
super.configure( configuration );
|
||||||
|
configuration.setProperty( AvailableSettings.WRAPPER_ARRAY_HANDLING, WrapperArrayHandling.ALLOW.name() );
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBoundedLongByteArrayAccess() {
|
public void testBoundedLongByteArrayAccess() {
|
||||||
byte[] original = buildRecursively(ARRAY_SIZE, true);
|
byte[] original = buildRecursively(ARRAY_SIZE, true);
|
||||||
|
|
|
@ -13,6 +13,7 @@ import jakarta.persistence.Lob;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
import org.hibernate.annotations.JavaType;
|
import org.hibernate.annotations.JavaType;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
@ -24,8 +25,10 @@ import org.hibernate.type.descriptor.jdbc.ArrayJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
||||||
|
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@ -40,6 +43,9 @@ import static org.hamcrest.Matchers.isOneOf;
|
||||||
*/
|
*/
|
||||||
@DomainModel(annotatedClasses = ByteArrayMappingTests.EntityOfByteArrays.class)
|
@DomainModel(annotatedClasses = ByteArrayMappingTests.EntityOfByteArrays.class)
|
||||||
@SessionFactory
|
@SessionFactory
|
||||||
|
@ServiceRegistry(
|
||||||
|
settings = @Setting(name = AvailableSettings.WRAPPER_ARRAY_HANDLING, value = "ALLOW")
|
||||||
|
)
|
||||||
public class ByteArrayMappingTests {
|
public class ByteArrayMappingTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -13,6 +13,7 @@ import jakarta.persistence.Lob;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
import org.hibernate.annotations.JavaType;
|
import org.hibernate.annotations.JavaType;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
@ -24,8 +25,10 @@ import org.hibernate.type.descriptor.jdbc.ArrayJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
||||||
|
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
@ -39,6 +42,9 @@ import static org.hamcrest.Matchers.isOneOf;
|
||||||
*/
|
*/
|
||||||
@DomainModel(annotatedClasses = CharacterArrayMappingTests.EntityWithCharArrays.class)
|
@DomainModel(annotatedClasses = CharacterArrayMappingTests.EntityWithCharArrays.class)
|
||||||
@SessionFactory
|
@SessionFactory
|
||||||
|
@ServiceRegistry(
|
||||||
|
settings = @Setting(name = AvailableSettings.WRAPPER_ARRAY_HANDLING, value = "ALLOW")
|
||||||
|
)
|
||||||
public class CharacterArrayMappingTests {
|
public class CharacterArrayMappingTests {
|
||||||
@Test
|
@Test
|
||||||
public void verifyMappings(SessionFactoryScope scope) {
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import jakarta.persistence.Table;
|
||||||
|
|
||||||
import org.hibernate.annotations.JavaType;
|
import org.hibernate.annotations.JavaType;
|
||||||
import org.hibernate.annotations.Nationalized;
|
import org.hibernate.annotations.Nationalized;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.dialect.NationalizationSupport;
|
import org.hibernate.dialect.NationalizationSupport;
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
@ -27,8 +28,10 @@ import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
||||||
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
@ -45,6 +48,9 @@ import static org.hamcrest.Matchers.isOneOf;
|
||||||
@DomainModel(annotatedClasses = CharacterArrayNationalizedMappingTests.EntityWithCharArrays.class)
|
@DomainModel(annotatedClasses = CharacterArrayNationalizedMappingTests.EntityWithCharArrays.class)
|
||||||
@SessionFactory
|
@SessionFactory
|
||||||
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsNationalizedData.class)
|
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsNationalizedData.class)
|
||||||
|
@ServiceRegistry(
|
||||||
|
settings = @Setting(name = AvailableSettings.WRAPPER_ARRAY_HANDLING, value = "ALLOW")
|
||||||
|
)
|
||||||
public class CharacterArrayNationalizedMappingTests {
|
public class CharacterArrayNationalizedMappingTests {
|
||||||
@Test
|
@Test
|
||||||
public void verifyMappings(SessionFactoryScope scope) {
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.mapping.basic;
|
||||||
|
|
||||||
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.internal.util.ExceptionHelper;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for mapping wrapper values
|
||||||
|
*/
|
||||||
|
@DomainModel(annotatedClasses = WrapperArrayHandlingDisallowTests.EntityOfByteArrays.class)
|
||||||
|
@SessionFactory
|
||||||
|
public class WrapperArrayHandlingDisallowTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyByteArrayMappings(SessionFactoryScope scope) {
|
||||||
|
try {
|
||||||
|
scope.getSessionFactory();
|
||||||
|
Assertions.fail( "Should fail boot validation!" );
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
final Throwable rootCause = ExceptionHelper.getRootCause( e );
|
||||||
|
Assertions.assertEquals( MappingException.class, rootCause.getClass() );
|
||||||
|
assertThat( rootCause.getMessage(), containsString( WrapperArrayHandlingDisallowTests.EntityOfByteArrays.class.getName() + "#wrapper" ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "EntityOfByteArrays")
|
||||||
|
@Table(name = "EntityOfByteArrays")
|
||||||
|
public static class EntityOfByteArrays {
|
||||||
|
@Id
|
||||||
|
public Integer id;
|
||||||
|
private Byte[] wrapper;
|
||||||
|
|
||||||
|
public EntityOfByteArrays() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,250 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.mapping.basic;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.Nationalized;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.dialect.NationalizationSupport;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Lob;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for mapping wrapper values
|
||||||
|
*/
|
||||||
|
@DomainModel(annotatedClasses = {
|
||||||
|
WrapperArrayHandlingLegacyTests.EntityOfByteArrays.class,
|
||||||
|
WrapperArrayHandlingLegacyTests.EntityWithCharArrays.class,
|
||||||
|
})
|
||||||
|
@SessionFactory
|
||||||
|
@ServiceRegistry(
|
||||||
|
settings = @Setting(name = AvailableSettings.WRAPPER_ARRAY_HANDLING, value = "LEGACY")
|
||||||
|
)
|
||||||
|
public class WrapperArrayHandlingLegacyTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyByteArrayMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodelImplementor mappingMetamodel = scope.getSessionFactory()
|
||||||
|
.getRuntimeMetamodels()
|
||||||
|
.getMappingMetamodel();
|
||||||
|
final JdbcTypeRegistry jdbcTypeRegistry = mappingMetamodel.getTypeConfiguration().getJdbcTypeRegistry();
|
||||||
|
final EntityPersister entityDescriptor = mappingMetamodel.getEntityDescriptor( WrapperArrayHandlingLegacyTests.EntityOfByteArrays.class);
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping primitive = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("primitive");
|
||||||
|
final JdbcMapping jdbcMapping = primitive.getJdbcMapping();
|
||||||
|
assertThat(jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo(byte[].class));
|
||||||
|
assertThat( jdbcMapping.getJdbcType(), equalTo( jdbcTypeRegistry.getDescriptor( Types.VARBINARY ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping primitive = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("wrapper");
|
||||||
|
final JdbcMapping jdbcMapping = primitive.getJdbcMapping();
|
||||||
|
assertThat(jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo(Byte[].class));
|
||||||
|
assertThat( jdbcMapping.getJdbcType(), equalTo( jdbcTypeRegistry.getDescriptor( Types.VARBINARY ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping primitive = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("primitiveLob");
|
||||||
|
final JdbcMapping jdbcMapping = primitive.getJdbcMapping();
|
||||||
|
assertThat(jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo(byte[].class));
|
||||||
|
assertThat( jdbcMapping.getJdbcType(), equalTo( jdbcTypeRegistry.getDescriptor( Types.BLOB ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping primitive = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("wrapperLob");
|
||||||
|
final JdbcMapping jdbcMapping = primitive.getJdbcMapping();
|
||||||
|
assertThat(jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo(Byte[].class));
|
||||||
|
assertThat( jdbcMapping.getJdbcType(), equalTo( jdbcTypeRegistry.getDescriptor( Types.BLOB ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist(
|
||||||
|
new EntityOfByteArrays( 1, "abc".getBytes(), new Byte[] { (byte) 1 })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.get( EntityOfByteArrays.class, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyCharacterArrayMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodelImplementor mappingMetamodel = scope.getSessionFactory()
|
||||||
|
.getRuntimeMetamodels()
|
||||||
|
.getMappingMetamodel();
|
||||||
|
final JdbcTypeRegistry jdbcRegistry = mappingMetamodel.getTypeConfiguration().getJdbcTypeRegistry();
|
||||||
|
final EntityPersister entityDescriptor = mappingMetamodel.getEntityDescriptor( WrapperArrayHandlingLegacyTests.EntityWithCharArrays.class);
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("primitive");
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJdbcType(), equalTo( jdbcRegistry.getDescriptor( Types.VARCHAR)));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("wrapper");
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJdbcType(), equalTo( jdbcRegistry.getDescriptor( Types.VARCHAR)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("primitiveClob");
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJdbcType(), equalTo( jdbcRegistry.getDescriptor( Types.CLOB)));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("wrapperClob");
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJdbcType(), equalTo( jdbcRegistry.getDescriptor( Types.CLOB)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyCharacterArrayNationalizedMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodelImplementor mappingMetamodel = scope.getSessionFactory()
|
||||||
|
.getRuntimeMetamodels()
|
||||||
|
.getMappingMetamodel();
|
||||||
|
final EntityPersister entityDescriptor = mappingMetamodel.getEntityDescriptor(
|
||||||
|
WrapperArrayHandlingLegacyTests.EntityWithCharArrays.class);
|
||||||
|
final JdbcTypeRegistry jdbcTypeRegistry = mappingMetamodel.getTypeConfiguration().getJdbcTypeRegistry();
|
||||||
|
|
||||||
|
final Dialect dialect = scope.getSessionFactory().getJdbcServices().getDialect();
|
||||||
|
final NationalizationSupport nationalizationSupport = dialect.getNationalizationSupport();
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("primitiveNVarchar");
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJdbcType(), is( jdbcTypeRegistry.getDescriptor( nationalizationSupport.getVarcharVariantCode())));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("wrapperNVarchar");
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJdbcType(), is( jdbcTypeRegistry.getDescriptor( nationalizationSupport.getVarcharVariantCode())));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("primitiveNClob");
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJdbcType(), is( jdbcTypeRegistry.getDescriptor( nationalizationSupport.getClobVariantCode())));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("wrapperNClob");
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJdbcType(), is( jdbcTypeRegistry.getDescriptor( nationalizationSupport.getClobVariantCode())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropTestData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.createMutationQuery("delete EntityOfByteArrays").executeUpdate();
|
||||||
|
session.createMutationQuery("delete EntityWithCharArrays").executeUpdate();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "EntityOfByteArrays")
|
||||||
|
@Table(name = "EntityOfByteArrays")
|
||||||
|
public static class EntityOfByteArrays {
|
||||||
|
@Id
|
||||||
|
public Integer id;
|
||||||
|
|
||||||
|
//tag::basic-bytearray-example[]
|
||||||
|
// mapped as VARBINARY
|
||||||
|
private byte[] primitive;
|
||||||
|
private Byte[] wrapper;
|
||||||
|
|
||||||
|
// mapped as (materialized) BLOB
|
||||||
|
@Lob
|
||||||
|
private byte[] primitiveLob;
|
||||||
|
@Lob
|
||||||
|
private Byte[] wrapperLob;
|
||||||
|
//end::basic-bytearray-example[]
|
||||||
|
|
||||||
|
public EntityOfByteArrays() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityOfByteArrays(Integer id, byte[] primitive, Byte[] wrapper) {
|
||||||
|
this.id = id;
|
||||||
|
this.primitive = primitive;
|
||||||
|
this.wrapper = wrapper;
|
||||||
|
this.primitiveLob = primitive;
|
||||||
|
this.wrapperLob = wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityOfByteArrays(Integer id, byte[] primitive, Byte[] wrapper, byte[] primitiveLob, Byte[] wrapperLob) {
|
||||||
|
this.id = id;
|
||||||
|
this.primitive = primitive;
|
||||||
|
this.wrapper = wrapper;
|
||||||
|
this.primitiveLob = primitiveLob;
|
||||||
|
this.wrapperLob = wrapperLob;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Entity(name = "EntityWithCharArrays")
|
||||||
|
@Table(name = "EntityWithCharArrays")
|
||||||
|
public static class EntityWithCharArrays {
|
||||||
|
@Id
|
||||||
|
public Integer id;
|
||||||
|
|
||||||
|
// mapped as VARCHAR
|
||||||
|
char[] primitive;
|
||||||
|
Character[] wrapper;
|
||||||
|
|
||||||
|
// mapped as CLOB
|
||||||
|
@Lob
|
||||||
|
char[] primitiveClob;
|
||||||
|
@Lob
|
||||||
|
Character[] wrapperClob;
|
||||||
|
|
||||||
|
// mapped as NVARCHAR
|
||||||
|
@Nationalized
|
||||||
|
char[] primitiveNVarchar;
|
||||||
|
@Nationalized
|
||||||
|
Character[] wrapperNVarchar;
|
||||||
|
|
||||||
|
// mapped as NCLOB
|
||||||
|
@Lob
|
||||||
|
@Nationalized
|
||||||
|
char[] primitiveNClob;
|
||||||
|
@Lob
|
||||||
|
@Nationalized
|
||||||
|
Character[] wrapperNClob;
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,25 +14,3 @@ earlier versions, see any other pertinent migration guides as well.
|
||||||
* link:{docsBase}/6.1/migration-guide/migration-guide.html[6.1 Migration guide]
|
* link:{docsBase}/6.1/migration-guide/migration-guide.html[6.1 Migration guide]
|
||||||
* link:{docsBase}/6.0/migration-guide/migration-guide.html[6.0 Migration guide]
|
* link:{docsBase}/6.0/migration-guide/migration-guide.html[6.0 Migration guide]
|
||||||
|
|
||||||
[[ddl-changes]]
|
|
||||||
== DDL type changes
|
|
||||||
|
|
||||||
[[ddl-offset-time]]
|
|
||||||
=== OffsetTime mapping changes
|
|
||||||
|
|
||||||
`OffsetTime` now depends on `@TimeZoneStorage` and the `hibernate.timezone.default_storage` setting.
|
|
||||||
Since the default for this setting is now `TimeZoneStorageType.DEFAULT`, this means that the DDL expectations for such columns changed.
|
|
||||||
|
|
||||||
If the target database supports time zone types natively like H2, Oracle, SQL Server and DB2 z/OS,
|
|
||||||
the type code `SqlTypes.TIME_WITH_TIMEZONE` is now used, which maps to the DDL type `time with time zone`.
|
|
||||||
|
|
||||||
Due to this change, schema validation errors could occur on existing databases.
|
|
||||||
|
|
||||||
The migration to `time with time zone` requires a migration expression like `cast(old as time with time zone)`
|
|
||||||
which will interpret the previous time as local time and compute the offset for the `time with time zone` based on the current date
|
|
||||||
and time zone settings of your database session.
|
|
||||||
|
|
||||||
If the target database does not support time zone types natively, Hibernate behaves just like before.
|
|
||||||
|
|
||||||
To retain backwards compatibility, configure the setting `hibernate.timezone.default_storage` to `NORMALIZE`.
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue