mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-16 16:15:06 +00:00
HHH-18806 fix nationalized strings on Sybase jTDS
Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
parent
1c87d73d2e
commit
1ef22c01f3
@ -15,58 +15,57 @@
|
||||
* @see Dialect#getNationalizationSupport()
|
||||
*/
|
||||
public enum NationalizationSupport {
|
||||
|
||||
/**
|
||||
* The {@code CHAR}, {@code VARCHAR}, and {@code CLOB}
|
||||
* types inherently handle nationalized character data.
|
||||
* Usually the database will not even define dedicated
|
||||
* nationalized data types like {@code NVARCHAR}.
|
||||
*/
|
||||
IMPLICIT( Types.CHAR, Types.VARCHAR, Types.LONGVARCHAR, Types.CLOB ),
|
||||
IMPLICIT,
|
||||
|
||||
/**
|
||||
* The database does define and support distinct SQL types
|
||||
* for representing nationalized character data, typically
|
||||
* named {@code NCHAR}, {@code NVARCHAR}, and {@code NCLOB}.
|
||||
*/
|
||||
EXPLICIT( Types.NCHAR, Types.NVARCHAR, Types.LONGNVARCHAR, Types.NCLOB ),
|
||||
EXPLICIT,
|
||||
|
||||
/**
|
||||
* The database does not even have support for nationalized
|
||||
* character data.
|
||||
*/
|
||||
UNSUPPORTED;
|
||||
|
||||
private final int charVariantCode;
|
||||
private final int varcharVariantCode;
|
||||
private final int longVarcharVariantCode;
|
||||
private final int clobVariantCode;
|
||||
|
||||
NationalizationSupport() {
|
||||
this( -1, -1, -1, -1 );
|
||||
}
|
||||
|
||||
NationalizationSupport(
|
||||
int charVariantCode,
|
||||
int varcharVariantCode,
|
||||
int longVarcharVariantCode,
|
||||
int clobVariantCode) {
|
||||
this.charVariantCode = charVariantCode;
|
||||
this.varcharVariantCode = varcharVariantCode;
|
||||
this.longVarcharVariantCode = longVarcharVariantCode;
|
||||
this.clobVariantCode = clobVariantCode;
|
||||
}
|
||||
|
||||
public int getCharVariantCode() {
|
||||
return charVariantCode;
|
||||
return switch ( this ) {
|
||||
case IMPLICIT -> Types.CHAR;
|
||||
case EXPLICIT -> Types.NCHAR;
|
||||
case UNSUPPORTED -> throw new UnsupportedOperationException("Nationalized character data not supported on this database");
|
||||
};
|
||||
}
|
||||
|
||||
public int getVarcharVariantCode() {
|
||||
return varcharVariantCode;
|
||||
return switch ( this ) {
|
||||
case IMPLICIT -> Types.VARCHAR;
|
||||
case EXPLICIT -> Types.NVARCHAR;
|
||||
case UNSUPPORTED -> throw new UnsupportedOperationException("Nationalized character data not supported on this database");
|
||||
};
|
||||
}
|
||||
|
||||
public int getLongVarcharVariantCode() {
|
||||
return longVarcharVariantCode;
|
||||
return switch ( this ) {
|
||||
case IMPLICIT -> Types.LONGVARCHAR;
|
||||
case EXPLICIT -> Types.LONGNVARCHAR;
|
||||
case UNSUPPORTED -> throw new UnsupportedOperationException("Nationalized character data not supported on this database");
|
||||
};
|
||||
}
|
||||
|
||||
public int getClobVariantCode() {
|
||||
return clobVariantCode;
|
||||
return switch ( this ) {
|
||||
case IMPLICIT -> Types.CLOB;
|
||||
case EXPLICIT -> Types.NCLOB;
|
||||
case UNSUPPORTED -> throw new UnsupportedOperationException("Nationalized character data not supported on this database");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -213,10 +213,7 @@ public void contributeTypes(TypeContributions typeContributions, ServiceRegistry
|
||||
|
||||
// The jTDS driver doesn't support the JDBC4 signatures using 'long length' for stream bindings
|
||||
jdbcTypeRegistry.addDescriptor( Types.CLOB, ClobJdbcType.CLOB_BINDING );
|
||||
|
||||
// The jTDS driver doesn't support nationalized types
|
||||
jdbcTypeRegistry.addDescriptor( Types.NCLOB, ClobJdbcType.CLOB_BINDING );
|
||||
jdbcTypeRegistry.addDescriptor( Types.NVARCHAR, ClobJdbcType.CLOB_BINDING );
|
||||
}
|
||||
else {
|
||||
// jConnect driver only conditionally supports getClob/getNClob depending on a server setting. See
|
||||
@ -254,7 +251,7 @@ public void contributeTypes(TypeContributions typeContributions, ServiceRegistry
|
||||
@Override
|
||||
public NationalizationSupport getNationalizationSupport() {
|
||||
// At least the jTDS driver doesn't support this
|
||||
return driverKind == SybaseDriverKind.JTDS ? NationalizationSupport.IMPLICIT : super.getNationalizationSupport();
|
||||
return super.getNationalizationSupport();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -29,7 +29,6 @@
|
||||
import org.hibernate.query.sqm.tree.expression.SqmXmlTableFunction;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.Template;
|
||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.internal.ColumnQualifierCollectorSqlAstWalker;
|
||||
import org.hibernate.sql.ast.spi.FromClauseAccess;
|
||||
|
@ -18,6 +18,8 @@
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
/**
|
||||
* Descriptor for {@link String} handling.
|
||||
*
|
||||
@ -68,6 +70,9 @@ public <X> X unwrap(String value, Class<X> type, WrapperOptions options) {
|
||||
if ( String.class.isAssignableFrom( type ) ) {
|
||||
return (X) value;
|
||||
}
|
||||
if ( byte[].class.isAssignableFrom( type ) ) {
|
||||
return (X) value.getBytes( UTF_8 );
|
||||
}
|
||||
if ( Reader.class.isAssignableFrom( type ) ) {
|
||||
return (X) new StringReader( value );
|
||||
}
|
||||
@ -103,6 +108,9 @@ public <X> String wrap(X value, WrapperOptions options) {
|
||||
if (value instanceof char[] chars) {
|
||||
return new String( chars );
|
||||
}
|
||||
if (value instanceof byte[] bytes) {
|
||||
return new String( bytes, UTF_8 );
|
||||
}
|
||||
if (value instanceof Reader reader) {
|
||||
return DataHelper.extractString( reader );
|
||||
}
|
||||
|
@ -105,7 +105,13 @@ public <X> ValueBinder<X> getBinder(final JavaType<X> javaType) {
|
||||
@Override
|
||||
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
|
||||
if ( options.getDialect().supportsNationalizedMethods() ) {
|
||||
st.setNString( index, javaType.unwrap( value, String.class, options ) );
|
||||
try {
|
||||
st.setNString( index, javaType.unwrap( value, String.class, options ) );
|
||||
}
|
||||
// workaround for jTDS driver for Sybase
|
||||
catch ( AbstractMethodError e ) {
|
||||
st.setBytes( index, javaType.unwrap( value, byte[].class, options ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
st.setString( index, javaType.unwrap( value, String.class, options ) );
|
||||
@ -131,7 +137,13 @@ public <X> ValueExtractor<X> getExtractor(final JavaType<X> javaType) {
|
||||
@Override
|
||||
protected X doExtract(ResultSet rs, int paramIndex, WrapperOptions options) throws SQLException {
|
||||
if ( options.getDialect().supportsNationalizedMethods() ) {
|
||||
return javaType.wrap( rs.getNString( paramIndex ), options );
|
||||
try {
|
||||
return javaType.wrap( rs.getNString( paramIndex ), options );
|
||||
}
|
||||
// workaround for jTDS driver for Sybase
|
||||
catch ( AbstractMethodError e ) {
|
||||
return javaType.wrap( rs.getBytes( paramIndex ), options );
|
||||
}
|
||||
}
|
||||
else {
|
||||
return javaType.wrap( rs.getString( paramIndex ), options );
|
||||
|
@ -8,10 +8,8 @@
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
import org.hibernate.annotations.Nationalized;
|
||||
import org.hibernate.dialect.SybaseASEDialect;
|
||||
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
|
||||
|
||||
import org.hibernate.testing.orm.junit.SkipForDialect;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
@ -20,8 +18,6 @@
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
@SkipForDialect(dialectClass = SybaseASEDialect.class,
|
||||
reason = "Error converting characters into server's character set")
|
||||
public class NationalizedTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
|
Loading…
x
Reference in New Issue
Block a user