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},
|
* {@link org.hibernate.type.descriptor.java.JavaType#getRecommendedJdbcType},
|
||||||
* or when the {@link org.hibernate.annotations.JdbcTypeCode @JdbcTypeCode}
|
* or when the {@link org.hibernate.annotations.JdbcTypeCode @JdbcTypeCode}
|
||||||
* annotation is used, for example.
|
* 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.jdbc.spi.JdbcTypeRegistry
|
||||||
|
* @see org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry
|
||||||
*
|
*
|
||||||
* @author Christian Beikov
|
* @author Christian Beikov
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -38,7 +38,7 @@ import org.hibernate.type.spi.TypeConfiguration;
|
||||||
public class ArrayJdbcType implements JdbcType {
|
public class ArrayJdbcType implements JdbcType {
|
||||||
|
|
||||||
public static final ArrayJdbcType INSTANCE = new ArrayJdbcType( ObjectJdbcType.INSTANCE );
|
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
|
@Override
|
||||||
protected Method computeValue(Class<?> type) {
|
protected Method computeValue(Class<?> type) {
|
||||||
try {
|
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 );
|
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,
|
// There are numerous missing methods that only have versions for positional parameter,
|
||||||
// but not named ones.
|
// but not named ones.
|
||||||
|
|
||||||
|
|
|
@ -7,18 +7,23 @@
|
||||||
package org.hibernate.type.descriptor.sql;
|
package org.hibernate.type.descriptor.sql;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.sql.Types;
|
|
||||||
|
|
||||||
import org.hibernate.Incubating;
|
import org.hibernate.Incubating;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.jdbc.Size;
|
import org.hibernate.engine.jdbc.Size;
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
|
||||||
import org.hibernate.metamodel.mapping.SqlExpressible;
|
import org.hibernate.metamodel.mapping.SqlExpressible;
|
||||||
import org.hibernate.type.SqlTypes;
|
import org.hibernate.type.SqlTypes;
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
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
|
* @author Christian Beikov
|
||||||
*/
|
*/
|
||||||
|
@ -46,20 +51,46 @@ public interface DdlType extends Serializable {
|
||||||
|
|
||||||
String getTypeNamePattern();
|
String getTypeNamePattern();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a type with length, precision, and scale specified by the given
|
||||||
|
* {@linkplain Size size object}.
|
||||||
|
*/
|
||||||
default String getTypeName(Size size) {
|
default String getTypeName(Size size) {
|
||||||
return getTypeName( size.getLength(), size.getPrecision(), size.getScale() );
|
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);
|
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);
|
String getCastTypeName(JdbcType jdbcType, JavaType<?> javaType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the name of the database type appropriate for casting operations
|
* Return the database type with the given length, precision, and scale,
|
||||||
* (via the CAST() SQL function) for the given {@link SqlExpressible}
|
* if specified, corresponding to the {@link SqlExpressible#getJdbcMapping()
|
||||||
* SQL type.
|
* 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) {
|
default String getCastTypeName(SqlExpressible type, Long length, Integer precision, Integer scale) {
|
||||||
return getCastTypeName(
|
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);
|
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;
|
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
|
* @author Christian Beikov
|
||||||
*
|
*
|
||||||
|
@ -42,10 +43,17 @@ public class DdlTypeRegistry implements Serializable {
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// baseline descriptors
|
// 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) {
|
public void addDescriptor(DdlType ddlType) {
|
||||||
addDescriptor( ddlType.getSqlTypeCode(), 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) {
|
public void addDescriptor(int sqlTypeCode, DdlType ddlType) {
|
||||||
final DdlType previous = ddlTypes.put( sqlTypeCode, ddlType );
|
final DdlType previous = ddlTypes.put( sqlTypeCode, ddlType );
|
||||||
if ( previous != null && previous != ddlType ) {
|
if ( previous != null && previous != ddlType ) {
|
||||||
|
@ -57,16 +65,29 @@ public class DdlTypeRegistry implements Serializable {
|
||||||
addSqlType( ddlType, sqlTypeCode );
|
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) {
|
public void addDescriptorIfAbsent(DdlType ddlType) {
|
||||||
addDescriptorIfAbsent( ddlType.getSqlTypeCode(), 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) {
|
public void addDescriptorIfAbsent(int sqlTypeCode, DdlType ddlType) {
|
||||||
if ( ddlTypes.putIfAbsent( sqlTypeCode, ddlType ) == null ) {
|
if ( ddlTypes.putIfAbsent( sqlTypeCode, ddlType ) == null ) {
|
||||||
addSqlType( ddlType, sqlTypeCode );
|
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) {
|
private void addSqlType(DdlType ddlType, int sqlTypeCode) {
|
||||||
for ( String rawTypeName : ddlType.getRawTypeNames() ) {
|
for ( String rawTypeName : ddlType.getRawTypeNames() ) {
|
||||||
final Integer previousSqlTypeCode = sqlTypes.put( rawTypeName, sqlTypeCode );
|
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) {
|
public Integer getSqlTypeCode(String rawTypeName) {
|
||||||
return sqlTypes.get( 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.
|
* Returns the registered {@link DdlType} for the given SQL type code.
|
||||||
* <p>
|
* <p>
|
||||||
* Not that the "long" types {@link Types#LONGVARCHAR}, {@link Types#LONGNVARCHAR}
|
* Note that the "long" types {@link Types#LONGVARCHAR}, {@link Types#LONGNVARCHAR},
|
||||||
* and {@link Types#LONGVARBINARY} are considered synonyms for their
|
* and {@link Types#LONGVARBINARY} are considered synonyms for their non-{@code LONG}
|
||||||
* non-{@code LONG} counterparts, with the only difference being that
|
* counterparts, with the only difference being that a different default length is
|
||||||
* a different default length is used: {@link org.hibernate.Length#LONG}
|
* used by default: {@link org.hibernate.Length#LONG} instead of
|
||||||
* instead of {@link org.hibernate.Length#DEFAULT}.
|
* {@link org.hibernate.Length#DEFAULT}.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public DdlType getDescriptor(int sqlTypeCode) {
|
public DdlType getDescriptor(int sqlTypeCode) {
|
||||||
|
@ -113,6 +135,15 @@ public class DdlTypeRegistry implements Serializable {
|
||||||
return ddlType;
|
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) {
|
public String getTypeName(int typeCode, Dialect dialect) {
|
||||||
// explicitly enforce dialect's default precisions
|
// explicitly enforce dialect's default precisions
|
||||||
switch ( typeCode ) {
|
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) {
|
public String getTypeName(int typeCode, Size size) {
|
||||||
return getTypeName( typeCode, size.getLength(), size.getPrecision(), size.getScale() );
|
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}
|
* 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}
|
* 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 typeCode the JDBC type code
|
||||||
* @param size the SQL length, if any
|
* @param size the SQL length, if any
|
||||||
* @param precision the SQL precision, if any
|
* @param precision the SQL precision, if any
|
||||||
* @param scale the SQL scale, if any
|
* @param scale the SQL scale, if any
|
||||||
*
|
*
|
||||||
* @return the associated name with smallest capacity >= size, if available and
|
* @return the associated type name with the smallest capacity that accommodates
|
||||||
* the default type name otherwise
|
* the given size, if available, and the default type name otherwise
|
||||||
*/
|
*/
|
||||||
public String getTypeName(int typeCode, Long size, Integer precision, Integer scale) {
|
public String getTypeName(int typeCode, Long size, Integer precision, Integer scale) {
|
||||||
final DdlType descriptor = getDescriptor( typeCode );
|
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
|
* Determines if there is a registered {@link DdlType} whose {@linkplain
|
||||||
* custom-registered type names).
|
* DdlType#getRawTypeName() raw type name} matches the given type name,
|
||||||
|
* taking into account DDL types registered by Hibernate.
|
||||||
*
|
*
|
||||||
* @param typeName the type name.
|
* @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) {
|
public boolean isTypeNameRegistered(final String typeName) {
|
||||||
for ( DdlType value : ddlTypes.values() ) {
|
for ( DdlType value : ddlTypes.values() ) {
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class ParameterTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
ParameterExpression<Integer[]> param = em.getCriteriaBuilder().parameter( Integer[].class, "theIntegers" );
|
ParameterExpression<Integer[]> param = em.getCriteriaBuilder().parameter( Integer[].class, "theIntegers" );
|
||||||
criteria.where( em.getCriteriaBuilder().equal( thePath, param ) );
|
criteria.where( em.getCriteriaBuilder().equal( thePath, param ) );
|
||||||
TypedQuery<MultiTypedBasicAttributesEntity> query = em.createQuery( criteria );
|
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 ) );
|
assertThat( query.getParameterValue( param.getName() ), instanceOf( Integer[].class ) );
|
||||||
query.getResultList();
|
query.getResultList();
|
||||||
em.getTransaction().commit();
|
em.getTransaction().commit();
|
||||||
|
@ -85,7 +85,7 @@ public class ParameterTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
);
|
);
|
||||||
|
|
||||||
TypedQuery<MultiTypedBasicAttributesEntity> query = em.createQuery( criteria );
|
TypedQuery<MultiTypedBasicAttributesEntity> query = em.createQuery( criteria );
|
||||||
Parameter parameter = query.getParameter( "id" );
|
Parameter<?> parameter = query.getParameter( "id" );
|
||||||
assertEquals( "id", parameter.getName() );
|
assertEquals( "id", parameter.getName() );
|
||||||
|
|
||||||
em.getTransaction().commit();
|
em.getTransaction().commit();
|
||||||
|
@ -140,7 +140,7 @@ public class ParameterTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class[] getAnnotatedClasses() {
|
public Class<?>[] getAnnotatedClasses() {
|
||||||
return new Class[] { MultiTypedBasicAttributesEntity.class };
|
return new Class[] { MultiTypedBasicAttributesEntity.class };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue