HHH-5869 - Add suport for nationalized character mappings
This commit is contained in:
parent
8e38db5833
commit
e7b188c924
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* Marks a character data type (String, Character, character, Clob) as being a nationalized variant
|
||||
* (NVARCHAR, NCHAR, NCLOB, etc).
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Target( { METHOD, FIELD } )
|
||||
@Retention( RUNTIME )
|
||||
public @interface Nationalized {
|
||||
}
|
|
@ -592,4 +592,6 @@ public interface AvailableSettings {
|
|||
* Default is to not store direct references.
|
||||
*/
|
||||
public static final String USE_DIRECT_REFERENCE_CACHE_ENTRIES = "hibernate.cache.use_reference_entries";
|
||||
|
||||
public static final String USE_NATIONALIZED_CHARACTER_DATA = "hibernate.use_nationalized_character_data";
|
||||
}
|
||||
|
|
|
@ -3144,6 +3144,19 @@ public class Configuration implements Serializable {
|
|||
return useNewGeneratorMappings.booleanValue();
|
||||
}
|
||||
|
||||
private Boolean useNationalizedCharacterData;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( {"UnnecessaryUnboxing"})
|
||||
public boolean useNationalizedCharacterData() {
|
||||
if ( useNationalizedCharacterData == null ) {
|
||||
final String booleanName = getConfigurationProperties()
|
||||
.getProperty( AvailableSettings.USE_NATIONALIZED_CHARACTER_DATA );
|
||||
useNationalizedCharacterData = Boolean.valueOf( booleanName );
|
||||
}
|
||||
return useNationalizedCharacterData.booleanValue();
|
||||
}
|
||||
|
||||
private Boolean forceDiscriminatorInSelectsByDefault;
|
||||
|
||||
@Override
|
||||
|
|
|
@ -765,6 +765,14 @@ public interface Mappings {
|
|||
*/
|
||||
public boolean useNewGeneratorMappings();
|
||||
|
||||
/**
|
||||
* Should we use nationalized variants of character data by default? This is controlled by the
|
||||
* {@link AvailableSettings#USE_NATIONALIZED_CHARACTER_DATA} setting.
|
||||
*
|
||||
* @return {@code true} if nationalized character data should be used by default; {@code false} otherwise.
|
||||
*/
|
||||
public boolean useNationalizedCharacterData();
|
||||
|
||||
/**
|
||||
* Return the property annotated with @ToOne and @Id if any.
|
||||
* Null otherwise
|
||||
|
|
|
@ -43,6 +43,7 @@ import javax.persistence.TemporalType;
|
|||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.annotations.Nationalized;
|
||||
import org.hibernate.annotations.Parameter;
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.hibernate.annotations.common.reflection.XClass;
|
||||
|
@ -62,10 +63,14 @@ import org.hibernate.internal.util.StringHelper;
|
|||
import org.hibernate.mapping.SimpleValue;
|
||||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.type.CharacterArrayClobType;
|
||||
import org.hibernate.type.CharacterArrayNClobType;
|
||||
import org.hibernate.type.CharacterNCharType;
|
||||
import org.hibernate.type.EnumType;
|
||||
import org.hibernate.type.PrimitiveCharacterArrayClobType;
|
||||
import org.hibernate.type.PrimitiveCharacterArrayNClobType;
|
||||
import org.hibernate.type.SerializableToBlobType;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.StringNVarcharType;
|
||||
import org.hibernate.type.WrappedMaterializedBlobType;
|
||||
import org.hibernate.usertype.DynamicParameterizedType;
|
||||
import org.jboss.logging.Logger;
|
||||
|
@ -155,6 +160,9 @@ public class SimpleValueBinder {
|
|||
typeParameters.clear();
|
||||
String type = BinderHelper.ANNOTATION_STRING_DEFAULT;
|
||||
|
||||
final boolean isNationalized = property.isAnnotationPresent( Nationalized.class )
|
||||
|| mappings.useNationalizedCharacterData();
|
||||
|
||||
Type annType = property.getAnnotation( Type.class );
|
||||
if ( annType != null ) {
|
||||
setExplicitType( annType );
|
||||
|
@ -200,19 +208,30 @@ public class SimpleValueBinder {
|
|||
}
|
||||
else if ( property.isAnnotationPresent( Lob.class ) ) {
|
||||
if ( mappings.getReflectionManager().equals( returnedClassOrElement, java.sql.Clob.class ) ) {
|
||||
type = "clob";
|
||||
type = isNationalized
|
||||
? StandardBasicTypes.NCLOB.getName()
|
||||
: StandardBasicTypes.CLOB.getName();
|
||||
}
|
||||
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, java.sql.NClob.class ) ) {
|
||||
type = StandardBasicTypes.NCLOB.getName();
|
||||
}
|
||||
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, java.sql.Blob.class ) ) {
|
||||
type = "blob";
|
||||
}
|
||||
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, String.class ) ) {
|
||||
type = StandardBasicTypes.MATERIALIZED_CLOB.getName();
|
||||
type = isNationalized
|
||||
? StandardBasicTypes.MATERIALIZED_NCLOB.getName()
|
||||
: StandardBasicTypes.MATERIALIZED_CLOB.getName();
|
||||
}
|
||||
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, Character.class ) && isArray ) {
|
||||
type = CharacterArrayClobType.class.getName();
|
||||
type = isNationalized
|
||||
? CharacterArrayNClobType.class.getName()
|
||||
: CharacterArrayClobType.class.getName();
|
||||
}
|
||||
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, char.class ) && isArray ) {
|
||||
type = PrimitiveCharacterArrayClobType.class.getName();
|
||||
type = isNationalized
|
||||
? PrimitiveCharacterArrayNClobType.class.getName()
|
||||
: PrimitiveCharacterArrayClobType.class.getName();
|
||||
}
|
||||
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, Byte.class ) && isArray ) {
|
||||
type = WrappedMaterializedBlobType.class.getName();
|
||||
|
@ -250,6 +269,24 @@ public class SimpleValueBinder {
|
|||
type = EnumType.class.getName();
|
||||
explicitType = type;
|
||||
}
|
||||
else if ( isNationalized ) {
|
||||
if ( mappings.getReflectionManager().equals( returnedClassOrElement, String.class ) ) {
|
||||
// nvarchar
|
||||
type = StringNVarcharType.INSTANCE.getName();
|
||||
explicitType = type;
|
||||
}
|
||||
else if ( mappings.getReflectionManager().equals( returnedClassOrElement, Character.class ) ) {
|
||||
if ( isArray ) {
|
||||
// nvarchar
|
||||
type = StringNVarcharType.INSTANCE.getName();
|
||||
}
|
||||
else {
|
||||
// nchar
|
||||
type = CharacterNCharType.INSTANCE.getName();
|
||||
}
|
||||
explicitType = type;
|
||||
}
|
||||
}
|
||||
|
||||
// implicit type will check basic types and Serializable classes
|
||||
if ( columns == null ) {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
package org.hibernate.engine.jdbc;
|
||||
import java.sql.Blob;
|
||||
import java.sql.Clob;
|
||||
import java.sql.NClob;
|
||||
|
||||
/**
|
||||
* Convenient base class for proxy-based LobCreator for handling wrapping.
|
||||
|
@ -38,11 +39,16 @@ public abstract class AbstractLobCreator implements LobCreator {
|
|||
|
||||
@Override
|
||||
public Clob wrap(Clob clob) {
|
||||
if ( SerializableNClobProxy.isNClob( clob ) ) {
|
||||
return SerializableNClobProxy.generateProxy( clob );
|
||||
if ( NClob.class.isInstance( clob ) ) {
|
||||
return wrap( (NClob) clob );
|
||||
}
|
||||
else {
|
||||
return SerializableClobProxy.generateProxy( clob );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NClob wrap(NClob nclob) {
|
||||
return SerializableNClobProxy.generateProxy( nclob );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,14 @@ public interface LobCreator {
|
|||
*/
|
||||
public Clob wrap(Clob clob);
|
||||
|
||||
/**
|
||||
* Wrap the given nclob in a serializable wrapper.
|
||||
*
|
||||
* @param nclob The nclob to be wrapped.
|
||||
* @return The wrapped nclob which will be castable to {@link NClob} as well as {@link WrappedNClob}.
|
||||
*/
|
||||
public NClob wrap(NClob nclob);
|
||||
|
||||
/**
|
||||
* Create a BLOB reference encapsulating the given byte array.
|
||||
*
|
||||
|
|
|
@ -25,6 +25,7 @@ package org.hibernate.engine.jdbc;
|
|||
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.sql.Clob;
|
||||
import java.sql.NClob;
|
||||
|
||||
/**
|
||||
* Manages aspects of proxying java.sql.NClobs to add serializability.
|
||||
|
@ -32,27 +33,10 @@ import java.sql.Clob;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SerializableNClobProxy extends SerializableClobProxy {
|
||||
private static final Class NCLOB_CLASS = loadNClobClassIfAvailable();
|
||||
|
||||
private static Class loadNClobClassIfAvailable() {
|
||||
try {
|
||||
return getProxyClassLoader().loadClass( "java.sql.NClob" );
|
||||
}
|
||||
catch ( ClassNotFoundException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Class[] PROXY_INTERFACES = new Class[] { determineNClobInterface(), WrappedClob.class };
|
||||
|
||||
private static Class determineNClobInterface() {
|
||||
// java.sql.NClob is a simple marker interface extending java.sql.Clob. So if java.sql.NClob is not available
|
||||
// on the classloader, just use java.sql.Clob
|
||||
return NCLOB_CLASS == null ? Clob.class : NCLOB_CLASS;
|
||||
}
|
||||
private static final Class[] PROXY_INTERFACES = new Class[] { NClob.class, WrappedNClob.class };
|
||||
|
||||
public static boolean isNClob(Clob clob) {
|
||||
return NCLOB_CLASS != null && NCLOB_CLASS.isInstance( clob );
|
||||
return NClob.class.isInstance( clob );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -67,16 +51,16 @@ public class SerializableNClobProxy extends SerializableClobProxy {
|
|||
}
|
||||
|
||||
/**
|
||||
* Generates a SerializableClobProxy proxy wrapping the provided Clob object.
|
||||
* Generates a SerializableNClobProxy proxy wrapping the provided NClob object.
|
||||
*
|
||||
* @param clob The Clob to wrap.
|
||||
* @param nclob The NClob to wrap.
|
||||
* @return The generated proxy.
|
||||
*/
|
||||
public static Clob generateProxy(Clob clob) {
|
||||
return ( Clob ) Proxy.newProxyInstance(
|
||||
public static NClob generateProxy(NClob nclob) {
|
||||
return ( NClob ) Proxy.newProxyInstance(
|
||||
getProxyClassLoader(),
|
||||
PROXY_INTERFACES,
|
||||
new SerializableNClobProxy( clob )
|
||||
new SerializableNClobProxy( nclob )
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc;
|
||||
|
||||
import java.sql.NClob;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface WrappedNClob extends WrappedClob {
|
||||
@Override
|
||||
@Deprecated
|
||||
public NClob getWrappedClob();
|
||||
|
||||
public NClob getWrappedNClob();
|
||||
}
|
|
@ -64,6 +64,8 @@ public class BasicTypeRegistry implements Serializable {
|
|||
register( BigIntegerType.INSTANCE );
|
||||
|
||||
register( StringType.INSTANCE );
|
||||
register( StringNVarcharType.INSTANCE );
|
||||
register( CharacterNCharType.INSTANCE );
|
||||
register( UrlType.INSTANCE );
|
||||
|
||||
register( DateType.INSTANCE );
|
||||
|
@ -87,10 +89,13 @@ public class BasicTypeRegistry implements Serializable {
|
|||
register( CharArrayType.INSTANCE );
|
||||
register( CharacterArrayType.INSTANCE );
|
||||
register( TextType.INSTANCE );
|
||||
register( NTextType.INSTANCE );
|
||||
register( BlobType.INSTANCE );
|
||||
register( MaterializedBlobType.INSTANCE );
|
||||
register( ClobType.INSTANCE );
|
||||
register( NClobType.INSTANCE );
|
||||
register( MaterializedClobType.INSTANCE );
|
||||
register( MaterializedNClobType.INSTANCE );
|
||||
register( SerializableType.INSTANCE );
|
||||
|
||||
register( ObjectType.INSTANCE );
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.type;
|
||||
|
||||
import org.hibernate.type.descriptor.java.CharacterArrayTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.NClobTypeDescriptor;
|
||||
|
||||
/**
|
||||
* A type that maps between {@link java.sql.Types#NCLOB NCLOB} and {@link Character Character[]}
|
||||
* <p/>
|
||||
* Essentially a {@link org.hibernate.type.MaterializedNClobType} but represented as a Character[] in Java rather than String.
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CharacterArrayNClobType extends AbstractSingleColumnStandardBasicType<Character[]> {
|
||||
public static final CharacterArrayNClobType INSTANCE = new CharacterArrayNClobType();
|
||||
|
||||
public CharacterArrayNClobType() {
|
||||
super( NClobTypeDescriptor.DEFAULT, CharacterArrayTypeDescriptor.INSTANCE );
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
// todo name these annotation types for addition to the registry
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.type;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.type.descriptor.java.CharacterTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.NCharTypeDescriptor;
|
||||
|
||||
/**
|
||||
* A type that maps between {@link java.sql.Types#NCHAR NCHAR(1)} and {@link Character}
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CharacterNCharType
|
||||
extends AbstractSingleColumnStandardBasicType<Character>
|
||||
implements PrimitiveType<Character>, DiscriminatorType<Character> {
|
||||
|
||||
public static final CharacterNCharType INSTANCE = new CharacterNCharType();
|
||||
|
||||
public CharacterNCharType() {
|
||||
super( NCharTypeDescriptor.INSTANCE, CharacterTypeDescriptor.INSTANCE );
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "ncharacter";
|
||||
}
|
||||
|
||||
public Serializable getDefaultValue() {
|
||||
throw new UnsupportedOperationException( "not a valid id type" );
|
||||
}
|
||||
|
||||
public Class getPrimitiveClass() {
|
||||
return char.class;
|
||||
}
|
||||
|
||||
public String objectToSQLString(Character value, Dialect dialect) {
|
||||
return '\'' + toString( value ) + '\'';
|
||||
}
|
||||
|
||||
public Character stringToObject(String xml) {
|
||||
return fromString( xml );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.type;
|
||||
|
||||
import org.hibernate.type.descriptor.java.StringTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.NClobTypeDescriptor;
|
||||
|
||||
/**
|
||||
* A type that maps between {@link java.sql.Types#CLOB CLOB} and {@link String}
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Gail Badner
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class MaterializedNClobType extends AbstractSingleColumnStandardBasicType<String> {
|
||||
public static final MaterializedNClobType INSTANCE = new MaterializedNClobType();
|
||||
|
||||
public MaterializedNClobType() {
|
||||
super( NClobTypeDescriptor.DEFAULT, StringTypeDescriptor.INSTANCE );
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "materialized_nclob";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.type;
|
||||
|
||||
import java.sql.NClob;
|
||||
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.type.descriptor.java.NClobTypeDescriptor;
|
||||
|
||||
/**
|
||||
* A type that maps between {@link java.sql.Types#CLOB CLOB} and {@link java.sql.Clob}
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NClobType extends AbstractSingleColumnStandardBasicType<NClob> {
|
||||
public static final NClobType INSTANCE = new NClobType();
|
||||
|
||||
public NClobType() {
|
||||
super( org.hibernate.type.descriptor.sql.NClobTypeDescriptor.DEFAULT, NClobTypeDescriptor.INSTANCE );
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "nclob";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean registerUnderJavaType() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NClob getReplacement(NClob original, NClob target, SessionImplementor session) {
|
||||
return session.getFactory().getDialect().getLobMergeStrategy().mergeNClob( original, target, session );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.type;
|
||||
|
||||
import org.hibernate.type.descriptor.java.StringTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.LongNVarcharTypeDescriptor;
|
||||
|
||||
/**
|
||||
* A type that maps between {@link java.sql.Types#LONGNVARCHAR LONGNVARCHAR} and {@link String}
|
||||
*
|
||||
* @author Gavin King,
|
||||
* @author Bertrand Renuart
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NTextType extends AbstractSingleColumnStandardBasicType<String> {
|
||||
public static final NTextType INSTANCE = new NTextType();
|
||||
|
||||
public NTextType() {
|
||||
super( LongNVarcharTypeDescriptor.INSTANCE, StringTypeDescriptor.INSTANCE );
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "ntext";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.type;
|
||||
|
||||
import org.hibernate.type.descriptor.java.PrimitiveCharacterArrayTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.NClobTypeDescriptor;
|
||||
|
||||
/**
|
||||
* Map a char[] to a NClob
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class PrimitiveCharacterArrayNClobType extends AbstractSingleColumnStandardBasicType<char[]> {
|
||||
public static final CharacterArrayClobType INSTANCE = new CharacterArrayClobType();
|
||||
|
||||
public PrimitiveCharacterArrayNClobType() {
|
||||
super( NClobTypeDescriptor.DEFAULT, PrimitiveCharacterArrayTypeDescriptor.INSTANCE );
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
// todo name these annotation types for addition to the registry
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -294,6 +294,15 @@ public class StandardBasicTypes {
|
|||
*/
|
||||
public static final TextType TEXT = TextType.INSTANCE;
|
||||
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link String} to JDBC {@link java.sql.Types#LONGNVARCHAR LONGNVARCHAR}.
|
||||
* <p/>
|
||||
* Similar to a {@link #MATERIALIZED_NCLOB}
|
||||
*
|
||||
* @see NTextType
|
||||
*/
|
||||
public static final NTextType NTEXT = NTextType.INSTANCE;
|
||||
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link java.sql.Clob} to JDBC {@link java.sql.Types#CLOB CLOB}.
|
||||
*
|
||||
|
@ -302,6 +311,14 @@ public class StandardBasicTypes {
|
|||
*/
|
||||
public static final ClobType CLOB = ClobType.INSTANCE;
|
||||
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link java.sql.NClob} to JDBC {@link java.sql.Types#NCLOB NCLOB}.
|
||||
*
|
||||
* @see NClobType
|
||||
* @see #MATERIALIZED_NCLOB
|
||||
*/
|
||||
public static final NClobType NCLOB = NClobType.INSTANCE;
|
||||
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link String} to JDBC {@link java.sql.Types#CLOB CLOB}.
|
||||
*
|
||||
|
@ -311,6 +328,15 @@ public class StandardBasicTypes {
|
|||
*/
|
||||
public static final MaterializedClobType MATERIALIZED_CLOB = MaterializedClobType.INSTANCE;
|
||||
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link String} to JDBC {@link java.sql.Types#NCLOB NCLOB}.
|
||||
*
|
||||
* @see MaterializedNClobType
|
||||
* @see #MATERIALIZED_CLOB
|
||||
* @see #NTEXT
|
||||
*/
|
||||
public static final MaterializedNClobType MATERIALIZED_NCLOB = MaterializedNClobType.INSTANCE;
|
||||
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link java.io.Serializable} to JDBC {@link java.sql.Types#VARBINARY VARBINARY}.
|
||||
* <p/>
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.type;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.type.descriptor.java.StringTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.NVarcharTypeDescriptor;
|
||||
|
||||
/**
|
||||
* A type that maps between {@link java.sql.Types#VARCHAR VARCHAR} and {@link String}
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StringNVarcharType
|
||||
extends AbstractSingleColumnStandardBasicType<String>
|
||||
implements DiscriminatorType<String> {
|
||||
|
||||
public static final StringNVarcharType INSTANCE = new StringNVarcharType();
|
||||
|
||||
public StringNVarcharType() {
|
||||
super( NVarcharTypeDescriptor.INSTANCE, StringTypeDescriptor.INSTANCE );
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "nstring";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean registerUnderJavaType() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String objectToSQLString(String value, Dialect dialect) throws Exception {
|
||||
return '\'' + value + '\'';
|
||||
}
|
||||
|
||||
public String stringToObject(String xml) throws Exception {
|
||||
return xml;
|
||||
}
|
||||
|
||||
public String toString(String value) {
|
||||
return value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.type.descriptor.java;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.NClob;
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.hibernate.engine.jdbc.CharacterStream;
|
||||
import org.hibernate.engine.jdbc.NClobImplementer;
|
||||
import org.hibernate.engine.jdbc.NClobProxy;
|
||||
import org.hibernate.engine.jdbc.WrappedNClob;
|
||||
import org.hibernate.engine.jdbc.internal.CharacterStreamImpl;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
|
||||
/**
|
||||
* Descriptor for {@link java.sql.NClob} handling.
|
||||
* <p/>
|
||||
* Note, {@link java.sql.NClob nclobs} really are mutable (their internal state can in fact be mutated). We simply
|
||||
* treat them as immutable because we cannot properly check them for changes nor deep copy them.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NClobTypeDescriptor extends AbstractTypeDescriptor<NClob> {
|
||||
public static final NClobTypeDescriptor INSTANCE = new NClobTypeDescriptor();
|
||||
|
||||
public static class NClobMutabilityPlan implements MutabilityPlan<NClob> {
|
||||
public static final NClobMutabilityPlan INSTANCE = new NClobMutabilityPlan();
|
||||
|
||||
public boolean isMutable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public NClob deepCopy(NClob value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Serializable disassemble(NClob value) {
|
||||
throw new UnsupportedOperationException( "Clobs are not cacheable" );
|
||||
}
|
||||
|
||||
public NClob assemble(Serializable cached) {
|
||||
throw new UnsupportedOperationException( "Clobs are not cacheable" );
|
||||
}
|
||||
}
|
||||
|
||||
public NClobTypeDescriptor() {
|
||||
super( NClob.class, NClobMutabilityPlan.INSTANCE );
|
||||
}
|
||||
|
||||
public String toString(NClob value) {
|
||||
return DataHelper.extractString( value );
|
||||
}
|
||||
|
||||
public NClob fromString(String string) {
|
||||
return NClobProxy.generateProxy( string );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public Comparator<NClob> getComparator() {
|
||||
return IncomparableComparator.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extractHashCode(NClob value) {
|
||||
return System.identityHashCode( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areEqual(NClob one, NClob another) {
|
||||
return one == another;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public <X> X unwrap(final NClob value, Class<X> type, WrapperOptions options) {
|
||||
if ( ! ( NClob.class.isAssignableFrom( type ) || CharacterStream.class.isAssignableFrom( type ) ) ) {
|
||||
throw unknownUnwrap( type );
|
||||
}
|
||||
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( CharacterStream.class.isAssignableFrom( type ) ) {
|
||||
if ( NClobImplementer.class.isInstance( value ) ) {
|
||||
// if the incoming Clob is a wrapper, just pass along its CharacterStream
|
||||
return (X) ( (NClobImplementer) value ).getUnderlyingStream();
|
||||
}
|
||||
else {
|
||||
// otherwise we need to build one...
|
||||
return (X) new CharacterStreamImpl( DataHelper.extractString( value ) );
|
||||
}
|
||||
}
|
||||
|
||||
final NClob clob = WrappedNClob.class.isInstance( value )
|
||||
? ( (WrappedNClob) value ).getWrappedNClob()
|
||||
: value;
|
||||
return (X) clob;
|
||||
}
|
||||
|
||||
public <X> NClob wrap(X value, WrapperOptions options) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( ! NClob.class.isAssignableFrom( value.getClass() ) ) {
|
||||
throw unknownWrap( value.getClass() );
|
||||
}
|
||||
|
||||
return options.getLobCreator().wrap( (NClob) value );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.nationalized;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Lob;
|
||||
|
||||
import java.sql.NClob;
|
||||
|
||||
import org.hibernate.annotations.Nationalized;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.type.MaterializedNClobType;
|
||||
import org.hibernate.type.NClobType;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.StringNVarcharType;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SimpleNationalizedTest extends BaseUnitTestCase {
|
||||
|
||||
@Entity( name="NationalizedEntity")
|
||||
public static class NationalizedEntity {
|
||||
@Id
|
||||
private Integer id;
|
||||
@Nationalized
|
||||
private String nvarcharAtt;
|
||||
@Lob
|
||||
@Nationalized
|
||||
private String materializedNclobAtt;
|
||||
@Lob
|
||||
@Nationalized
|
||||
private NClob nclobAtt;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleNationalizedTest() {
|
||||
Configuration cfg = new Configuration();
|
||||
cfg.addAnnotatedClass( NationalizedEntity.class );
|
||||
cfg.buildMappings();
|
||||
PersistentClass pc = cfg.getClassMapping( NationalizedEntity.class.getName() );
|
||||
assertNotNull( pc );
|
||||
|
||||
{
|
||||
Property prop = pc.getProperty( "nvarcharAtt" );
|
||||
assertSame( StringNVarcharType.INSTANCE, prop.getType() );
|
||||
}
|
||||
|
||||
{
|
||||
Property prop = pc.getProperty( "materializedNclobAtt" );
|
||||
assertSame( MaterializedNClobType.INSTANCE, prop.getType() );
|
||||
}
|
||||
|
||||
{
|
||||
Property prop = pc.getProperty( "nclobAtt" );
|
||||
assertSame( NClobType.INSTANCE, prop.getType() );
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue