finish off jdoc for DDLTypes
This commit is contained in:
parent
867b1146ab
commit
1d5f6b5c13
|
@ -24,8 +24,13 @@ import java.sql.Types;
|
|||
* {@link org.hibernate.type.descriptor.java.JavaType#getRecommendedJdbcType},
|
||||
* or when the {@link org.hibernate.annotations.JdbcTypeCode @JdbcTypeCode}
|
||||
* annotation is used, for example.
|
||||
* <p>
|
||||
* A type code may also be used as a key to obtain a dialect-specific
|
||||
* {@link org.hibernate.type.descriptor.sql.DdlType} for the purposes of
|
||||
* generating DDL.
|
||||
*
|
||||
* @see org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry
|
||||
* @see org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry
|
||||
*
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
|
|
|
@ -38,7 +38,7 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
public class ArrayJdbcType implements JdbcType {
|
||||
|
||||
public static final ArrayJdbcType INSTANCE = new ArrayJdbcType( ObjectJdbcType.INSTANCE );
|
||||
private static final ClassValue<Method> NAME_BINDER = new ClassValue<Method>() {
|
||||
private static final ClassValue<Method> NAME_BINDER = new ClassValue<>() {
|
||||
@Override
|
||||
protected Method computeValue(Class<?> type) {
|
||||
try {
|
||||
|
@ -137,7 +137,7 @@ public class ArrayJdbcType implements JdbcType {
|
|||
throw new HibernateException( "JDBC driver does not support named parameters for setArray. Use positional.", ex );
|
||||
}
|
||||
}
|
||||
// Not that it's supposed to have setArray(String,Array) by standard.
|
||||
// Note that it's supposed to have setArray(String,Array) by standard.
|
||||
// There are numerous missing methods that only have versions for positional parameter,
|
||||
// but not named ones.
|
||||
|
||||
|
|
|
@ -7,18 +7,23 @@
|
|||
package org.hibernate.type.descriptor.sql;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.Size;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.SqlExpressible;
|
||||
import org.hibernate.type.SqlTypes;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
|
||||
/**
|
||||
* Descriptor for a DDL type.
|
||||
* Descriptor for a DDL column type. An instance of this type abstracts over
|
||||
* a parameterized family of {@linkplain Dialect dialect-specific} SQL types
|
||||
* with the same {@linkplain #getSqlTypeCode() type code} but varying length,
|
||||
* precision, and scale. Usually, the types belonging to the family share a
|
||||
* single {@linkplain #getRawTypeName() type name} in SQL, but in certain
|
||||
* cases, most notably, in the case of the MySQL LOB types {@code text} and
|
||||
* {@code blob}, it's the type name itself which is parameter-dependent.
|
||||
*
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
|
@ -46,20 +51,46 @@ public interface DdlType extends Serializable {
|
|||
|
||||
String getTypeNamePattern();
|
||||
|
||||
/**
|
||||
* Return a type with length, precision, and scale specified by the given
|
||||
* {@linkplain Size size object}.
|
||||
*/
|
||||
default String getTypeName(Size size) {
|
||||
return getTypeName( size.getLength(), size.getPrecision(), size.getScale() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a type with the given length, precision, and scale.
|
||||
*/
|
||||
String getTypeName(Long size, Integer precision, Integer scale);
|
||||
|
||||
/**
|
||||
* Return the database type corresponding to the given {@link JdbcType}
|
||||
* that may be used as a target type in casting operations using the SQL
|
||||
* {@code CAST()} function, using the given {@link JavaType} to help
|
||||
* determine the appropriate precision and scale. The length is usually
|
||||
* chosen to be the maximum possible length for the dialect.
|
||||
*
|
||||
* @see JavaType#getDefaultSqlScale(Dialect, JdbcType)
|
||||
* @see JavaType#getDefaultSqlPrecision(Dialect, JdbcType)
|
||||
* @see Dialect#getMaxVarcharLength()
|
||||
*
|
||||
* @return The SQL type name
|
||||
*/
|
||||
String getCastTypeName(JdbcType jdbcType, JavaType<?> javaType);
|
||||
|
||||
/**
|
||||
* Get the name of the database type appropriate for casting operations
|
||||
* (via the CAST() SQL function) for the given {@link SqlExpressible}
|
||||
* SQL type.
|
||||
* Return the database type with the given length, precision, and scale,
|
||||
* if specified, corresponding to the {@link SqlExpressible#getJdbcMapping()
|
||||
* JdbcMapping} of the given {@link SqlExpressible}, that may be used as a
|
||||
* target type in casting operations using the SQL {@code CAST()} function.
|
||||
*
|
||||
* @return The database type name
|
||||
* @param type the {@link SqlExpressible}
|
||||
* @param length the length, or null, if unspecified
|
||||
* @param precision the precision, or null, if unspecified
|
||||
* @param scale the scale, or null, if unspecified
|
||||
*
|
||||
* @return The SQL type name
|
||||
*/
|
||||
default String getCastTypeName(SqlExpressible type, Long length, Integer precision, Integer scale) {
|
||||
return getCastTypeName(
|
||||
|
@ -71,5 +102,20 @@ public interface DdlType extends Serializable {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the database type with the given length, precision, and scale,
|
||||
* if specified, corresponding to the given {@link JdbcType}, that may
|
||||
* be used as a target type in casting operations using the SQL
|
||||
* {@code CAST()} function, using the given {@link JavaType} to help
|
||||
* determine the appropriate precision and scale. The length, if not
|
||||
* explicitly specified, is usually chosen to be the maximum possible
|
||||
* length for the dialect.
|
||||
*
|
||||
* @see JavaType#getDefaultSqlScale(Dialect, JdbcType)
|
||||
* @see JavaType#getDefaultSqlPrecision(Dialect, JdbcType)
|
||||
* @see Dialect#getMaxVarcharLength()
|
||||
*
|
||||
* @return The SQL type name
|
||||
*/
|
||||
String getCastTypeName(JdbcType jdbcType, JavaType<?> javaType, Long length, Integer precision, Integer scale);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,8 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Basically a map from SQL type code (int) -> {@link DdlType}
|
||||
* A registry mapping {@link org.hibernate.type.SqlTypes JDBC type codes}
|
||||
* to instances of the {@link DdlType} interface.
|
||||
*
|
||||
* @author Christian Beikov
|
||||
*
|
||||
|
@ -42,10 +43,17 @@ public class DdlTypeRegistry implements Serializable {
|
|||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// baseline descriptors
|
||||
|
||||
/**
|
||||
* Add a mapping from the {@linkplain DdlType#getSqlTypeCode() type code}
|
||||
* of the given {@link DdlType} to the given {@code DdlType}.
|
||||
*/
|
||||
public void addDescriptor(DdlType ddlType) {
|
||||
addDescriptor( ddlType.getSqlTypeCode(), ddlType );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a mapping from the given type code to the given {@link DdlType}.
|
||||
*/
|
||||
public void addDescriptor(int sqlTypeCode, DdlType ddlType) {
|
||||
final DdlType previous = ddlTypes.put( sqlTypeCode, ddlType );
|
||||
if ( previous != null && previous != ddlType ) {
|
||||
|
@ -57,16 +65,29 @@ public class DdlTypeRegistry implements Serializable {
|
|||
addSqlType( ddlType, sqlTypeCode );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a mapping from the {@linkplain DdlType#getSqlTypeCode() type code}
|
||||
* of the given {@link DdlType} to the given {@code DdlType}, if there
|
||||
* is no mapping already present for that type code.
|
||||
*/
|
||||
public void addDescriptorIfAbsent(DdlType ddlType) {
|
||||
addDescriptorIfAbsent( ddlType.getSqlTypeCode(), ddlType );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a mapping from the given type code to the given {@link DdlType},
|
||||
* if there is no mapping already present for the given type code.
|
||||
*/
|
||||
public void addDescriptorIfAbsent(int sqlTypeCode, DdlType ddlType) {
|
||||
if ( ddlTypes.putIfAbsent( sqlTypeCode, ddlType ) == null ) {
|
||||
addSqlType( ddlType, sqlTypeCode );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a mapping from the given type code to the raw type name of the
|
||||
* given {@link DdlType}.
|
||||
*/
|
||||
private void addSqlType(DdlType ddlType, int sqlTypeCode) {
|
||||
for ( String rawTypeName : ddlType.getRawTypeNames() ) {
|
||||
final Integer previousSqlTypeCode = sqlTypes.put( rawTypeName, sqlTypeCode );
|
||||
|
@ -78,7 +99,8 @@ public class DdlTypeRegistry implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link SqlTypes} type code for the given DDL raw type name, or <code>null</code> if it is unknown.
|
||||
* Returns the {@link SqlTypes} type code for the given DDL raw type name, or
|
||||
* {@code null} if the type code cannot be determined from the registrations.
|
||||
*/
|
||||
public Integer getSqlTypeCode(String rawTypeName) {
|
||||
return sqlTypes.get( rawTypeName );
|
||||
|
@ -87,11 +109,11 @@ public class DdlTypeRegistry implements Serializable {
|
|||
/**
|
||||
* Returns the registered {@link DdlType} for the given SQL type code.
|
||||
* <p>
|
||||
* Not that the "long" types {@link Types#LONGVARCHAR}, {@link Types#LONGNVARCHAR}
|
||||
* and {@link Types#LONGVARBINARY} are considered synonyms for their
|
||||
* non-{@code LONG} counterparts, with the only difference being that
|
||||
* a different default length is used: {@link org.hibernate.Length#LONG}
|
||||
* instead of {@link org.hibernate.Length#DEFAULT}.
|
||||
* Note that the "long" types {@link Types#LONGVARCHAR}, {@link Types#LONGNVARCHAR},
|
||||
* and {@link Types#LONGVARBINARY} are considered synonyms for their non-{@code LONG}
|
||||
* counterparts, with the only difference being that a different default length is
|
||||
* used by default: {@link org.hibernate.Length#LONG} instead of
|
||||
* {@link org.hibernate.Length#DEFAULT}.
|
||||
*
|
||||
*/
|
||||
public DdlType getDescriptor(int sqlTypeCode) {
|
||||
|
@ -113,6 +135,15 @@ public class DdlTypeRegistry implements Serializable {
|
|||
return ddlType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL type name for the specified {@link java.sql.Types JDBC type code},
|
||||
* filling in the placemarkers {@code $l}, {@code $p}, and {@code $s}
|
||||
* with the default length, precision, and scale for the given SQL dialect.
|
||||
*
|
||||
* @param typeCode the JDBC type code
|
||||
* @param dialect the dialect which determines the default length, precision, and scale
|
||||
* @return a SQL column type
|
||||
*/
|
||||
public String getTypeName(int typeCode, Dialect dialect) {
|
||||
// explicitly enforce dialect's default precisions
|
||||
switch ( typeCode ) {
|
||||
|
@ -133,6 +164,19 @@ public class DdlTypeRegistry implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL type name for the specified {@link java.sql.Types JDBC type code}
|
||||
* and size, filling in the placemarkers {@code $l}, {@code $p}, and {@code $s}
|
||||
* with the length, precision, and scale determined by the given {@linkplain Size
|
||||
* size object}. The returned type name should be of a SQL type large enough to
|
||||
* accommodate values of the specified size.
|
||||
*
|
||||
* @param typeCode the JDBC type code
|
||||
* @param size an object which determines the length, precision, and scale
|
||||
*
|
||||
* @return the associated type name with the smallest capacity that accommodates
|
||||
* the given size, if available, and the default type name otherwise
|
||||
*/
|
||||
public String getTypeName(int typeCode, Size size) {
|
||||
return getTypeName( typeCode, size.getLength(), size.getPrecision(), size.getScale() );
|
||||
}
|
||||
|
@ -140,15 +184,16 @@ public class DdlTypeRegistry implements Serializable {
|
|||
/**
|
||||
* Get the SQL type name for the specified {@link java.sql.Types JDBC type code}
|
||||
* and size, filling in the placemarkers {@code $l}, {@code $p}, and {@code $s}
|
||||
* with the given length, precision, and scale.
|
||||
* with the given length, precision, and scale. The returned type name should be
|
||||
* of a SQL type large enough to accommodate values of the specified size.
|
||||
*
|
||||
* @param typeCode the JDBC type code
|
||||
* @param size the SQL length, if any
|
||||
* @param precision the SQL precision, if any
|
||||
* @param scale the SQL scale, if any
|
||||
*
|
||||
* @return the associated name with smallest capacity >= size, if available and
|
||||
* the default type name otherwise
|
||||
* @return the associated type name with the smallest capacity that accommodates
|
||||
* the given size, if available, and the default type name otherwise
|
||||
*/
|
||||
public String getTypeName(int typeCode, Long size, Integer precision, Integer scale) {
|
||||
final DdlType descriptor = getDescriptor( typeCode );
|
||||
|
@ -165,12 +210,13 @@ public class DdlTypeRegistry implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Whether or not the given type name has been registered for this dialect (including both hibernate type names and
|
||||
* custom-registered type names).
|
||||
* Determines if there is a registered {@link DdlType} whose {@linkplain
|
||||
* DdlType#getRawTypeName() raw type name} matches the given type name,
|
||||
* taking into account DDL types registered by Hibernate.
|
||||
*
|
||||
* @param typeName the type name.
|
||||
*
|
||||
* @return true if the given string has been registered either as a hibernate type or as a custom-registered one
|
||||
* @return {@code true} if there is a DDL type with the given raw type name
|
||||
*/
|
||||
public boolean isTypeNameRegistered(final String typeName) {
|
||||
for ( DdlType value : ddlTypes.values() ) {
|
||||
|
|
|
@ -62,7 +62,7 @@ public class ParameterTest extends BaseEntityManagerFunctionalTestCase {
|
|||
ParameterExpression<Integer[]> param = em.getCriteriaBuilder().parameter( Integer[].class, "theIntegers" );
|
||||
criteria.where( em.getCriteriaBuilder().equal( thePath, param ) );
|
||||
TypedQuery<MultiTypedBasicAttributesEntity> query = em.createQuery( criteria );
|
||||
query.setParameter( param, new Integer[] { Integer.valueOf(1), Integer.valueOf(1), Integer.valueOf(1) } );
|
||||
query.setParameter( param, new Integer[] {1, 1, 1} );
|
||||
assertThat( query.getParameterValue( param.getName() ), instanceOf( Integer[].class ) );
|
||||
query.getResultList();
|
||||
em.getTransaction().commit();
|
||||
|
@ -85,7 +85,7 @@ public class ParameterTest extends BaseEntityManagerFunctionalTestCase {
|
|||
);
|
||||
|
||||
TypedQuery<MultiTypedBasicAttributesEntity> query = em.createQuery( criteria );
|
||||
Parameter parameter = query.getParameter( "id" );
|
||||
Parameter<?> parameter = query.getParameter( "id" );
|
||||
assertEquals( "id", parameter.getName() );
|
||||
|
||||
em.getTransaction().commit();
|
||||
|
@ -140,7 +140,7 @@ public class ParameterTest extends BaseEntityManagerFunctionalTestCase {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Class[] getAnnotatedClasses() {
|
||||
public Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] { MultiTypedBasicAttributesEntity.class };
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue