Search in sources :

Example 1 with SqlTypeDescriptor

use of org.hibernate.type.descriptor.sql.SqlTypeDescriptor in project hibernate-orm by hibernate.

the class TypeOverrideTest method testNonStandardSqlTypeDescriptor.

@Test
public void testNonStandardSqlTypeDescriptor() {
    // no override
    SqlTypeDescriptor sqlTypeDescriptor = new IntegerTypeDescriptor() {

        @Override
        public boolean canBeRemapped() {
            return false;
        }
    };
    assertSame(sqlTypeDescriptor, remapSqlTypeDescriptor(sqlTypeDescriptor));
}
Also used : SqlTypeDescriptor(org.hibernate.type.descriptor.sql.SqlTypeDescriptor) IntegerTypeDescriptor(org.hibernate.type.descriptor.sql.IntegerTypeDescriptor) Test(org.junit.Test)

Example 2 with SqlTypeDescriptor

use of org.hibernate.type.descriptor.sql.SqlTypeDescriptor in project hibernate-orm by hibernate.

the class TypeOverrideTest method testDialectWithNonStandardSqlTypeDescriptor.

@Test
public void testDialectWithNonStandardSqlTypeDescriptor() {
    assertNotSame(VarcharTypeDescriptor.INSTANCE, StoredPrefixedStringType.INSTANCE.getSqlTypeDescriptor());
    final Dialect dialect = new H2DialectOverridePrefixedVarcharSqlTypeDesc();
    final SqlTypeDescriptor remapped = remapSqlTypeDescriptor(dialect, StoredPrefixedStringType.PREFIXED_VARCHAR_TYPE_DESCRIPTOR);
    assertSame(VarcharTypeDescriptor.INSTANCE, remapped);
}
Also used : SqlTypeDescriptor(org.hibernate.type.descriptor.sql.SqlTypeDescriptor) SkipForDialect(org.hibernate.testing.SkipForDialect) SybaseASE15Dialect(org.hibernate.dialect.SybaseASE15Dialect) PostgreSQL81Dialect(org.hibernate.dialect.PostgreSQL81Dialect) Dialect(org.hibernate.dialect.Dialect) SybaseDialect(org.hibernate.dialect.SybaseDialect) PostgreSQLDialect(org.hibernate.dialect.PostgreSQLDialect) Test(org.junit.Test)

Example 3 with SqlTypeDescriptor

use of org.hibernate.type.descriptor.sql.SqlTypeDescriptor in project hibernate-orm by hibernate.

the class AbstractSharedSessionContract method remapSqlTypeDescriptor.

@Override
public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
    if (!sqlTypeDescriptor.canBeRemapped()) {
        return sqlTypeDescriptor;
    }
    final Dialect dialect = getJdbcServices().getJdbcEnvironment().getDialect();
    final SqlTypeDescriptor remapped = dialect.remapSqlTypeDescriptor(sqlTypeDescriptor);
    return remapped == null ? sqlTypeDescriptor : remapped;
}
Also used : SqlTypeDescriptor(org.hibernate.type.descriptor.sql.SqlTypeDescriptor) Dialect(org.hibernate.dialect.Dialect)

Example 4 with SqlTypeDescriptor

use of org.hibernate.type.descriptor.sql.SqlTypeDescriptor in project hibernate-orm by hibernate.

the class SimpleValue method buildAttributeConverterTypeAdapter.

/**
	 * Build a Hibernate Type that incorporates the JPA AttributeConverter.  AttributeConverter works totally in
	 * memory, meaning it converts between one Java representation (the entity attribute representation) and another
	 * (the value bound into JDBC statements or extracted from results).  However, the Hibernate Type system operates
	 * at the lower level of actually dealing directly with those JDBC objects.  So even though we have an
	 * AttributeConverter, we still need to "fill out" the rest of the BasicType data and bridge calls
	 * to bind/extract through the converter.
	 * <p/>
	 * Essentially the idea here is that an intermediate Java type needs to be used.  Let's use an example as a means
	 * to illustrate...  Consider an {@code AttributeConverter<Integer,String>}.  This tells Hibernate that the domain
	 * model defines this attribute as an Integer value (the 'entityAttributeJavaType'), but that we need to treat the
	 * value as a String (the 'databaseColumnJavaType') when dealing with JDBC (aka, the database type is a
	 * VARCHAR/CHAR):<ul>
	 *     <li>
	 *         When binding values to PreparedStatements we need to convert the Integer value from the entity
	 *         into a String and pass that String to setString.  The conversion is handled by calling
	 *         {@link AttributeConverter#convertToDatabaseColumn(Object)}
	 *     </li>
	 *     <li>
	 *         When extracting values from ResultSets (or CallableStatement parameters) we need to handle the
	 *         value via getString, and convert that returned String to an Integer.  That conversion is handled
	 *         by calling {@link AttributeConverter#convertToEntityAttribute(Object)}
	 *     </li>
	 * </ul>
	 *
	 * @return The built AttributeConverter -> Type adapter
	 *
	 * @todo : ultimately I want to see attributeConverterJavaType and attributeConverterJdbcTypeCode specify-able separately
	 * then we can "play them against each other" in terms of determining proper typing
	 *
	 * @todo : see if we already have previously built a custom on-the-fly BasicType for this AttributeConverter; see note below about caching
	 */
@SuppressWarnings("unchecked")
private Type buildAttributeConverterTypeAdapter() {
    // todo : validate the number of columns present here?
    final Class entityAttributeJavaType = attributeConverterDescriptor.getDomainType();
    final Class databaseColumnJavaType = attributeConverterDescriptor.getJdbcType();
    // resolve the JavaTypeDescriptor ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // For the JavaTypeDescriptor portion we simply resolve the "entity attribute representation" part of
    // the AttributeConverter to resolve the corresponding descriptor.
    final JavaTypeDescriptor entityAttributeJavaTypeDescriptor = JavaTypeDescriptorRegistry.INSTANCE.getDescriptor(entityAttributeJavaType);
    // build the SqlTypeDescriptor adapter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Going back to the illustration, this should be a SqlTypeDescriptor that handles the Integer <-> String
    //		conversions.  This is the more complicated piece.  First we need to determine the JDBC type code
    //		corresponding to the AttributeConverter's declared "databaseColumnJavaType" (how we read that value out
    // 		of ResultSets).  See JdbcTypeJavaClassMappings for details.  Again, given example, this should return
    // 		VARCHAR/CHAR
    int jdbcTypeCode = JdbcTypeJavaClassMappings.INSTANCE.determineJdbcTypeCodeForJavaClass(databaseColumnJavaType);
    if (isLob()) {
        if (LobTypeMappings.INSTANCE.hasCorrespondingLobCode(jdbcTypeCode)) {
            jdbcTypeCode = LobTypeMappings.INSTANCE.getCorrespondingLobCode(jdbcTypeCode);
        } else {
            if (Serializable.class.isAssignableFrom(entityAttributeJavaType)) {
                jdbcTypeCode = Types.BLOB;
            } else {
                throw new IllegalArgumentException(String.format(Locale.ROOT, "JDBC type-code [%s (%s)] not known to have a corresponding LOB equivalent, and Java type is not Serializable (to use BLOB)", jdbcTypeCode, JdbcTypeNameMapper.getTypeName(jdbcTypeCode)));
            }
        }
    }
    if (isNationalized()) {
        jdbcTypeCode = NationalizedTypeMappings.INSTANCE.getCorrespondingNationalizedCode(jdbcTypeCode);
    }
    // find the standard SqlTypeDescriptor for that JDBC type code (allow itr to be remapped if needed!)
    final SqlTypeDescriptor sqlTypeDescriptor = metadata.getMetadataBuildingOptions().getServiceRegistry().getService(JdbcServices.class).getJdbcEnvironment().getDialect().remapSqlTypeDescriptor(SqlTypeDescriptorRegistry.INSTANCE.getDescriptor(jdbcTypeCode));
    // find the JavaTypeDescriptor representing the "intermediate database type representation".  Back to the
    // 		illustration, this should be the type descriptor for Strings
    final JavaTypeDescriptor intermediateJavaTypeDescriptor = JavaTypeDescriptorRegistry.INSTANCE.getDescriptor(databaseColumnJavaType);
    // and finally construct the adapter, which injects the AttributeConverter calls into the binding/extraction
    // 		process...
    final SqlTypeDescriptor sqlTypeDescriptorAdapter = new AttributeConverterSqlTypeDescriptorAdapter(attributeConverterDescriptor.getAttributeConverter(), sqlTypeDescriptor, intermediateJavaTypeDescriptor);
    // todo : cache the AttributeConverterTypeAdapter in case that AttributeConverter is applied multiple times.
    final String name = AttributeConverterTypeAdapter.NAME_PREFIX + attributeConverterDescriptor.getAttributeConverter().getClass().getName();
    final String description = String.format("BasicType adapter for AttributeConverter<%s,%s>", entityAttributeJavaType.getSimpleName(), databaseColumnJavaType.getSimpleName());
    return new AttributeConverterTypeAdapter(name, description, attributeConverterDescriptor.getAttributeConverter(), sqlTypeDescriptorAdapter, entityAttributeJavaType, databaseColumnJavaType, entityAttributeJavaTypeDescriptor);
}
Also used : SqlTypeDescriptor(org.hibernate.type.descriptor.sql.SqlTypeDescriptor) AttributeConverterSqlTypeDescriptorAdapter(org.hibernate.type.descriptor.converter.AttributeConverterSqlTypeDescriptorAdapter) JdbcServices(org.hibernate.engine.jdbc.spi.JdbcServices) AttributeConverterTypeAdapter(org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter) JavaTypeDescriptor(org.hibernate.type.descriptor.java.JavaTypeDescriptor)

Aggregations

SqlTypeDescriptor (org.hibernate.type.descriptor.sql.SqlTypeDescriptor)4 Dialect (org.hibernate.dialect.Dialect)2 Test (org.junit.Test)2 PostgreSQL81Dialect (org.hibernate.dialect.PostgreSQL81Dialect)1 PostgreSQLDialect (org.hibernate.dialect.PostgreSQLDialect)1 SybaseASE15Dialect (org.hibernate.dialect.SybaseASE15Dialect)1 SybaseDialect (org.hibernate.dialect.SybaseDialect)1 JdbcServices (org.hibernate.engine.jdbc.spi.JdbcServices)1 SkipForDialect (org.hibernate.testing.SkipForDialect)1 AttributeConverterSqlTypeDescriptorAdapter (org.hibernate.type.descriptor.converter.AttributeConverterSqlTypeDescriptorAdapter)1 AttributeConverterTypeAdapter (org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter)1 JavaTypeDescriptor (org.hibernate.type.descriptor.java.JavaTypeDescriptor)1 IntegerTypeDescriptor (org.hibernate.type.descriptor.sql.IntegerTypeDescriptor)1