HHH-16535 introduce @Array annotation

This commit is contained in:
Gavin 2023-05-02 13:49:12 +03:00 committed by Gavin King
parent 57029ddc70
commit a56942ce3b
17 changed files with 117 additions and 36 deletions

View File

@ -746,7 +746,7 @@ public class OracleLegacyDialect extends Dialect {
}
@Override
public String getArrayTypeName(String javaElementTypeName, String elementTypeName) {
public String getArrayTypeName(String javaElementTypeName, String elementTypeName, Integer maxLength) {
return javaElementTypeName + "Array";
}

View File

@ -0,0 +1,30 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.annotations;
import org.hibernate.Incubating;
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;
/**
* Specifies the maximum length of a SQL array type mapped by
* the annotated attribute. For example:
* <pre>
*
* </pre>
*/
@Incubating
@Target({FIELD, METHOD})
@Retention( RUNTIME )
public @interface Array {
int length();
}

View File

@ -7,7 +7,6 @@
package org.hibernate.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.hibernate.Incubating;
@ -15,33 +14,32 @@ import org.hibernate.Incubating;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Specifies the UDT (user defined type) name for the annotated embeddable or embedded.
*
* Specifies the UDT (user defined type) name for the annotated embeddable
* type or embedded attribute.
* <p>
* This annotation may be applied to an embeddable class:
* <pre>
* Example:
*
* {@code @Embeddable}
* {@code Struct(name = "CUST")}
* public class Customer { ... }
* {@code @Embeddable}
* {@code Struct(name = "CUST")}
* public class Customer { ... }
* </pre>
*
* Alternatively, it may be applied to an embedded attribute:
* <pre>
* Example:
*
* public class Order {
* {@code Embedded}
* {@code Struct(name = "CUST")}
* private Customer customer;
* }
* public class Order {
* {@code Embedded}
* {@code Struct(name = "CUST")}
* private Customer customer;
* }
* </pre>
*
* @since 6.2
*/
@Incubating
@Target({TYPE, FIELD, METHOD})
@Retention( RetentionPolicy.RUNTIME )
@Retention( RUNTIME )
public @interface Struct {
/**
* The name of the UDT (user defined type).

View File

@ -11,6 +11,7 @@ import java.util.List;
import java.util.Map;
import org.hibernate.AnnotationException;
import org.hibernate.annotations.Array;
import org.hibernate.annotations.Check;
import org.hibernate.annotations.Checks;
import org.hibernate.annotations.ColumnDefault;
@ -75,6 +76,7 @@ public class AnnotatedColumn {
private Long length;
private Integer precision;
private Integer scale;
private Integer arrayLength;
private String logicalColumnName;
private boolean unique;
private boolean nullable = true;
@ -120,6 +122,14 @@ public class AnnotatedColumn {
return scale;
}
public Integer getArrayLength() {
return arrayLength;
}
public void setArrayLength(Integer arrayLength) {
this.arrayLength = arrayLength;
}
public boolean isUnique() {
return unique;
}
@ -228,6 +238,7 @@ public class AnnotatedColumn {
length,
precision,
scale,
arrayLength,
nullable,
sqlType,
unique,
@ -257,6 +268,7 @@ public class AnnotatedColumn {
Long length,
Integer precision,
Integer scale,
Integer arrayLength,
boolean nullable,
String sqlType,
boolean unique,
@ -273,6 +285,7 @@ public class AnnotatedColumn {
mappingColumn.setPrecision( precision );
mappingColumn.setScale( scale );
}
mappingColumn.setArrayLength( arrayLength );
mappingColumn.setNullable( nullable );
mappingColumn.setSqlType( sqlType );
mappingColumn.setUnique( unique );
@ -732,6 +745,9 @@ public class AnnotatedColumn {
annotatedColumn.setLength( (long) column.length() );
annotatedColumn.setPrecision( column.precision() );
annotatedColumn.setScale( column.scale() );
if ( inferredData.getProperty().isAnnotationPresent(Array.class) ) {
annotatedColumn.setArrayLength( inferredData.getProperty().getAnnotation(Array.class).length() );
}
// annotatedColumn.setPropertyHolder( propertyHolder );
// annotatedColumn.setPropertyName( getRelativePath( propertyHolder, inferredData.getPropertyName() ) );
annotatedColumn.setNullable( column.nullable() ); //TODO force to not null if available? This is a (bad) user choice.

View File

@ -311,9 +311,11 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
final Column mappingColumn = getMappingColumn();
initMappingColumn(
columnName,
null, referencedColumn.getLength(),
null,
referencedColumn.getLength(),
referencedColumn.getPrecision(),
referencedColumn.getScale(),
referencedColumn.getArrayLength(),
mappingColumn != null && mappingColumn.isNullable(),
referencedColumn.getSqlType(),
mappingColumn != null && mappingColumn.isUnique(),
@ -339,6 +341,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
column.getLength(),
column.getPrecision(),
column.getScale(),
column.getArrayLength(),
getMappingColumn().isNullable(),
column.getSqlType(),
getMappingColumn().isUnique(),
@ -390,6 +393,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
mappingColumn.setLength( column.getLength() );
mappingColumn.setPrecision( column.getPrecision() );
mappingColumn.setScale( column.getScale() );
mappingColumn.setArrayLength( column.getArrayLength() );
}
}

View File

@ -247,5 +247,6 @@ public class CopyIdentifierComponentSecondPass extends FkSecondPass {
mappingColumn.setLength( column.getLength() );
mappingColumn.setPrecision( column.getPrecision() );
mappingColumn.setScale( column.getScale() );
mappingColumn.setArrayLength( column.getArrayLength() );
}
}

View File

@ -4192,8 +4192,15 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
*
* @since 6.1
*/
public String getArrayTypeName(String javaElementTypeName, String elementTypeName) {
return supportsStandardArrays() ? elementTypeName + " array" : null;
public String getArrayTypeName(String javaElementTypeName, String elementTypeName, Integer maxLength) {
if ( supportsStandardArrays() ) {
return maxLength == null
? elementTypeName + " array"
: elementTypeName + " array[" + maxLength + "]";
}
else {
return null;
}
}
/**

View File

@ -1295,8 +1295,8 @@ public class DialectDelegateWrapper extends Dialect {
}
@Override
public String getArrayTypeName(String javaElementTypeName, String elementTypeName) {
return wrapped.getArrayTypeName( javaElementTypeName, elementTypeName );
public String getArrayTypeName(String javaElementTypeName, String elementTypeName, Integer maxLength) {
return wrapped.getArrayTypeName( javaElementTypeName, elementTypeName, maxLength );
}
@Override

View File

@ -66,11 +66,8 @@ public class OracleArrayJdbcType implements JdbcType {
Integer precision,
Integer scale,
TypeConfiguration typeConfiguration) {
final JavaType<Object> elementJavaType = elementJdbcType.getJdbcRecommendedJavaTypeMapping(
precision,
scale,
typeConfiguration
);
final JavaType<Object> elementJavaType =
elementJdbcType.getJdbcRecommendedJavaTypeMapping( precision, scale, typeConfiguration );
return typeConfiguration.getJavaTypeRegistry().resolveDescriptor(
Array.newInstance( elementJavaType.getJavaTypeClass(), 0 ).getClass()
);
@ -173,6 +170,7 @@ public class OracleArrayJdbcType implements JdbcType {
static String getTypeName(JavaType<?> elementJavaType, Dialect dialect) {
return dialect.getArrayTypeName(
elementJavaType.getJavaTypeClass().getSimpleName(),
null, // not needed by OracleDialect.getArrayTypeName()
null // not needed by OracleDialect.getArrayTypeName()
);
}
@ -199,11 +197,12 @@ public class OracleArrayJdbcType implements JdbcType {
),
new BasicTypeImpl<>( elementJavaType, getElementJdbcType() )
);
int arrayLength = columnSize.getArrayLength() == null ? 127 : columnSize.getArrayLength();
database.addAuxiliaryDatabaseObject(
new NamedAuxiliaryDatabaseObject(
elementTypeName,
database.getDefaultNamespace(),
getCreateArrayTypeCommand( elementTypeName, elementType ),
getCreateArrayTypeCommand( elementTypeName, arrayLength, elementType ),
getDropArrayTypeCommand( elementTypeName ),
emptySet(),
true
@ -211,10 +210,10 @@ public class OracleArrayJdbcType implements JdbcType {
);
}
String[] getCreateArrayTypeCommand(String elementTypeName, String elementType) {
String[] getCreateArrayTypeCommand(String elementTypeName, int length, String elementType) {
return new String[]{
"create or replace type " + elementTypeName
+ " as varying array(255) of " + elementType
+ " as varying array(" + length + ") of " + elementType
};
}

View File

@ -785,7 +785,7 @@ public class OracleDialect extends Dialect {
}
@Override
public String getArrayTypeName(String javaElementTypeName, String elementTypeName) {
public String getArrayTypeName(String javaElementTypeName, String elementTypeName, Integer maxLength) {
return javaElementTypeName + "Array";
}

View File

@ -188,7 +188,7 @@ public class SpannerDialect extends Dialect {
}
@Override
public String getArrayTypeName(String javaElementTypeName, String elementTypeName) {
public String getArrayTypeName(String javaElementTypeName, String elementTypeName, Integer maxLength) {
return "ARRAY<" + elementTypeName + ">";
}

View File

@ -47,6 +47,7 @@ public class Size implements Serializable {
private Integer scale;
private Long length;
private Integer arrayLength;
private LobMultiplier lobMultiplier;
public Size() {
@ -106,6 +107,10 @@ public class Size implements Serializable {
return length;
}
public Integer getArrayLength() {
return arrayLength;
}
public LobMultiplier getLobMultiplier() {
return lobMultiplier;
}
@ -131,6 +136,11 @@ public class Size implements Serializable {
return this;
}
public Size setArrayLength(Integer arrayLength) {
this.arrayLength = arrayLength;
return this;
}
public Size setLobMultiplier(LobMultiplier lobMultiplier) {
this.lobMultiplier = lobMultiplier;
return this;

View File

@ -23,6 +23,7 @@ public class AggregateColumn extends Column {
setLength( column.getLength() );
setPrecision( column.getPrecision() );
setScale( column.getScale() );
setArrayLength( column.getArrayLength() );
setValue( column.getValue() );
setTypeIndex( column.getTypeIndex() );
setName( column.getQuotedName() );

View File

@ -48,6 +48,7 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
private Long length;
private Integer precision;
private Integer scale;
private Integer arrayLength;
private Value value;
private int typeIndex;
private String name;
@ -86,6 +87,14 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
this.length = length.longValue();
}
public Integer getArrayLength() {
return arrayLength;
}
public void setArrayLength(Integer arrayLength) {
this.arrayLength = arrayLength;
}
public Value getValue() {
return value;
}
@ -392,13 +401,15 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
throw new AssertionFailure( "no typing information available to determine column size" );
}
final JdbcMapping jdbcMapping = (JdbcMapping) type;
return dialect.getSizeStrategy().resolveSize(
Size size = dialect.getSizeStrategy().resolveSize(
jdbcMapping.getJdbcType(),
jdbcMapping.getJdbcJavaType(),
precision,
scale,
length
);
size.setArrayLength( arrayLength );
return size;
}
private Type getTypeForComponentValue(Mapping mapping, Type type, int typeIndex) {
@ -675,6 +686,7 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
copy.length = length;
copy.precision = precision;
copy.scale = scale;
copy.arrayLength = arrayLength;
copy.value = value;
copy.typeIndex = typeIndex;
copy.name = name;

View File

@ -141,6 +141,7 @@ public class ForeignKey extends Constraint {
referencingColumn.setLength( referencedColumn.getLength() );
referencingColumn.setScale( referencedColumn.getScale() );
referencingColumn.setPrecision( referencedColumn.getPrecision() );
referencingColumn.setArrayLength( referencedColumn.getArrayLength() );
}
}
}

View File

@ -6130,7 +6130,8 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
);
final String arrayTypeName = dialect.getArrayTypeName(
javaTypeDescriptor.getElementJavaType().getJavaTypeClass().getSimpleName(),
elementTypeName
elementTypeName,
null
);
if ( arrayTypeName != null ) {
appendSql( arrayTypeName );

View File

@ -44,7 +44,8 @@ public class ArrayDdlTypeImpl extends DdlTypeImpl {
);
return dialect.getArrayTypeName(
javaTypeDescriptor.getElementJavaType().getJavaTypeClass().getSimpleName(),
arrayElementTypeName
arrayElementTypeName,
columnSize.getArrayLength()
);
}