HHH-17448 Add newly standard column annotation attributes to Hibernate column annotations
This commit is contained in:
parent
ec556f0fa5
commit
0b964a3f19
|
@ -68,4 +68,22 @@ public @interface TimeZoneColumn {
|
|||
*/
|
||||
String table() default "";
|
||||
|
||||
/**
|
||||
* (Optional) The SQL fragment that is used when
|
||||
* generating the DDL for the column.
|
||||
* <p>
|
||||
* The DDL must be written in the native SQL dialect
|
||||
* of the target database (it is not portable across databases).
|
||||
*
|
||||
* @since 7.0
|
||||
*/
|
||||
String options() default "";
|
||||
|
||||
/**
|
||||
* (Optional) A comment to be applied to the column.
|
||||
*
|
||||
* @since 7.0
|
||||
*/
|
||||
String comment() default "";
|
||||
|
||||
}
|
||||
|
|
|
@ -504,6 +504,8 @@ public abstract class AbstractPropertyHolder implements PropertyHolder {
|
|||
created.nullable( column.nullable() );
|
||||
|
||||
if ( timeZoneColumn != null ) {
|
||||
created.options( timeZoneColumn.options() );
|
||||
created.comment( timeZoneColumn.comment() );
|
||||
created.table( timeZoneColumn.table() );
|
||||
created.insertable( timeZoneColumn.insertable() );
|
||||
created.updatable( timeZoneColumn.updatable() );
|
||||
|
@ -514,6 +516,8 @@ public abstract class AbstractPropertyHolder implements PropertyHolder {
|
|||
created.insertable( column.insertable() );
|
||||
created.updatable( column.updatable() );
|
||||
created.columnDefinition( column.columnDefinition() );
|
||||
created.options( column.options() );
|
||||
created.comment( column.comment() );
|
||||
}
|
||||
|
||||
return created;
|
||||
|
|
|
@ -99,6 +99,8 @@ public class AnnotatedColumn {
|
|||
|
||||
private String options;
|
||||
|
||||
private String comment;
|
||||
|
||||
public AnnotatedColumns getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
@ -267,9 +269,9 @@ public class AnnotatedColumn {
|
|||
}
|
||||
mappingColumn.setOptions( options );
|
||||
|
||||
// if ( isNotEmpty( comment ) ) {
|
||||
// mappingColumn.setComment( comment );
|
||||
// }
|
||||
if ( isNotEmpty( comment ) ) {
|
||||
mappingColumn.setComment( comment );
|
||||
}
|
||||
if ( generatedAs != null ) {
|
||||
mappingColumn.setGeneratedAs( generatedAs );
|
||||
}
|
||||
|
@ -318,6 +320,7 @@ public class AnnotatedColumn {
|
|||
}
|
||||
mappingColumn.setDefaultValue( defaultValue );
|
||||
mappingColumn.setOptions( options );
|
||||
mappingColumn.setComment( comment );
|
||||
|
||||
if ( writeExpression != null ) {
|
||||
final int numberOfJdbcParams = StringHelper.count( writeExpression, '?' );
|
||||
|
@ -814,6 +817,7 @@ public class AnnotatedColumn {
|
|||
annotatedColumn.applyGeneratedAs( inferredData, numberOfColumns );
|
||||
annotatedColumn.applyColumnCheckConstraint( column );
|
||||
annotatedColumn.applyColumnOptions( column );
|
||||
annotatedColumn.applyColumnComment(column);
|
||||
annotatedColumn.applyCheckConstraint( inferredData, numberOfColumns );
|
||||
annotatedColumn.extractDataFromPropertyData( propertyHolder, inferredData, sourceModelContext );
|
||||
annotatedColumn.bind();
|
||||
|
@ -1036,6 +1040,12 @@ public class AnnotatedColumn {
|
|||
options = column.options();
|
||||
}
|
||||
|
||||
private void applyColumnComment(jakarta.persistence.Column column) {
|
||||
if ( !column.comment().isEmpty() ) {
|
||||
comment = column.comment();
|
||||
}
|
||||
}
|
||||
|
||||
void setOptions(String options){
|
||||
this.options = options;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ public class TimeZoneColumnAnnotation implements TimeZoneColumn {
|
|||
private boolean updatable;
|
||||
private String columnDefinition;
|
||||
private String table;
|
||||
private String options;
|
||||
private String comment;
|
||||
|
||||
/**
|
||||
* Used in creating dynamic annotation instances (e.g. from XML)
|
||||
|
@ -34,6 +36,8 @@ public class TimeZoneColumnAnnotation implements TimeZoneColumn {
|
|||
this.updatable = true;
|
||||
this.columnDefinition = "";
|
||||
this.table = "";
|
||||
this.options = "";
|
||||
this.comment = "";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,6 +49,8 @@ public class TimeZoneColumnAnnotation implements TimeZoneColumn {
|
|||
this.updatable = annotation.updatable();
|
||||
this.columnDefinition = annotation.columnDefinition();
|
||||
this.table = annotation.table();
|
||||
this.options = annotation.options();
|
||||
this.comment = annotation.comment();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,6 +77,8 @@ public class TimeZoneColumnAnnotation implements TimeZoneColumn {
|
|||
modelContext
|
||||
);
|
||||
this.table = extractJandexValue( annotation, HibernateAnnotations.TIME_ZONE_COLUMN, "table", modelContext );
|
||||
this.options = extractJandexValue( annotation, HibernateAnnotations.TIME_ZONE_COLUMN, "options", modelContext );
|
||||
this.comment = extractJandexValue( annotation, HibernateAnnotations.TIME_ZONE_COLUMN, "comment", modelContext );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -127,5 +135,21 @@ public class TimeZoneColumnAnnotation implements TimeZoneColumn {
|
|||
this.table = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String options() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public void options(String value) {
|
||||
this.options = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String comment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public void comment(String value) {
|
||||
this.comment = value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
package org.hibernate.orm.test.schemaupdate;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.time.OffsetTime;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.hibernate.annotations.TimeZoneColumn;
|
||||
import org.hibernate.annotations.TimeZoneStorage;
|
||||
import org.hibernate.annotations.TimeZoneStorageType;
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.tool.hbm2ddl.SchemaExport;
|
||||
import org.hibernate.tool.schema.TargetType;
|
||||
|
||||
import org.hibernate.testing.orm.junit.BaseUnitTest;
|
||||
import org.hibernate.testing.orm.junit.JiraKey;
|
||||
import org.hibernate.testing.util.ServiceRegistryUtil;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@BaseUnitTest
|
||||
@JiraKey("HHH-17448")
|
||||
public class TimeZoneColumnTest {
|
||||
|
||||
private File output;
|
||||
private StandardServiceRegistry ssr;
|
||||
private MetadataImplementor metadata;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws IOException {
|
||||
output = File.createTempFile( "update_script", ".sql" );
|
||||
output.deleteOnExit();
|
||||
ssr = ServiceRegistryUtil.serviceRegistry();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearsDown() {
|
||||
output.delete();
|
||||
StandardServiceRegistryBuilder.destroy( ssr );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTableCommentAreCreated() throws Exception {
|
||||
createSchema( TestEntity.class );
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions( output, "birthtime_offset_offset", "option_1" ),
|
||||
"TimeZoneColumn options have not been created "
|
||||
);
|
||||
JdbcEnvironment jdbcEnvironment = ssr.getService( JdbcEnvironment.class );
|
||||
Dialect dialect = jdbcEnvironment.getDialect();
|
||||
if ( dialect.supportsCommentOn() ) {
|
||||
assertTrue(
|
||||
tableCreationStatementContainsComment( output, "birthtime_offset_offset", "This is a comment" ),
|
||||
"TimeZoneColumn comment have not been created "
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void createSchema(Class... annotatedClasses) {
|
||||
final MetadataSources metadataSources = new MetadataSources( ssr );
|
||||
|
||||
for ( Class c : annotatedClasses ) {
|
||||
metadataSources.addAnnotatedClass( c );
|
||||
}
|
||||
metadata = (MetadataImplementor) metadataSources.buildMetadata();
|
||||
metadata.orderColumns( false );
|
||||
metadata.validate();
|
||||
new SchemaExport()
|
||||
.setHaltOnError( true )
|
||||
.setOutputFile( output.getAbsolutePath() )
|
||||
.setFormat( false )
|
||||
.createOnly( EnumSet.of( TargetType.SCRIPT ), metadata );
|
||||
}
|
||||
|
||||
private static boolean tableCreationStatementContainsOptions(
|
||||
File output,
|
||||
String columnName,
|
||||
String options) throws Exception {
|
||||
String[] fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase()
|
||||
.split( System.lineSeparator() );
|
||||
for ( int i = 0; i < fileContent.length; i++ ) {
|
||||
String statement = fileContent[i].toUpperCase( Locale.ROOT );
|
||||
if ( statement.contains( options.toUpperCase( Locale.ROOT ) ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean tableCreationStatementContainsComment(
|
||||
File output,
|
||||
String columnName,
|
||||
String comment) throws Exception {
|
||||
|
||||
String[] fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase()
|
||||
.split( System.lineSeparator() );
|
||||
for ( int i = 0; i < fileContent.length; i++ ) {
|
||||
String statement = fileContent[i].toUpperCase( Locale.ROOT );
|
||||
if ( statement.contains( comment.toUpperCase( Locale.ROOT ) ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Entity(name = "TestEntity")
|
||||
public static class TestEntity {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@TimeZoneStorage(TimeZoneStorageType.COLUMN)
|
||||
@TimeZoneColumn(name = "birthtime_offset_offset", comment = "This is a comment", options = "option_1")
|
||||
@Column(name = "birthtime_offset")
|
||||
private OffsetTime offsetTimeColumn;
|
||||
|
||||
// @TimeZoneStorage(TimeZoneStorageType.COLUMN)
|
||||
// @TimeZoneColumn(name = "birthday_zoned_offset")
|
||||
// @Column(name = "birthday_zoned")
|
||||
// private ZonedDateTime zonedDateTimeColumn;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue