Skip to content

Commit 0b964a3

Browse files
dreab8sebersole
authored andcommitted
HHH-17448 Add newly standard column annotation attributes to Hibernate column annotations
1 parent ec556f0 commit 0b964a3

File tree

5 files changed

+198
-3
lines changed

5 files changed

+198
-3
lines changed

hibernate-core/src/main/java/org/hibernate/annotations/TimeZoneColumn.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,22 @@
6868
*/
6969
String table() default "";
7070

71+
/**
72+
* (Optional) The SQL fragment that is used when
73+
* generating the DDL for the column.
74+
* <p>
75+
* The DDL must be written in the native SQL dialect
76+
* of the target database (it is not portable across databases).
77+
*
78+
* @since 7.0
79+
*/
80+
String options() default "";
81+
82+
/**
83+
* (Optional) A comment to be applied to the column.
84+
*
85+
* @since 7.0
86+
*/
87+
String comment() default "";
88+
7189
}

hibernate-core/src/main/java/org/hibernate/boot/model/internal/AbstractPropertyHolder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,8 @@ private static Column createTimeZoneColumn(
504504
created.nullable( column.nullable() );
505505

506506
if ( timeZoneColumn != null ) {
507+
created.options( timeZoneColumn.options() );
508+
created.comment( timeZoneColumn.comment() );
507509
created.table( timeZoneColumn.table() );
508510
created.insertable( timeZoneColumn.insertable() );
509511
created.updatable( timeZoneColumn.updatable() );
@@ -514,6 +516,8 @@ private static Column createTimeZoneColumn(
514516
created.insertable( column.insertable() );
515517
created.updatable( column.updatable() );
516518
created.columnDefinition( column.columnDefinition() );
519+
created.options( column.options() );
520+
created.comment( column.comment() );
517521
}
518522

519523
return created;

hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedColumn.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ public class AnnotatedColumn {
9999

100100
private String options;
101101

102+
private String comment;
103+
102104
public AnnotatedColumns getParent() {
103105
return parent;
104106
}
@@ -267,9 +269,9 @@ public void bind() {
267269
}
268270
mappingColumn.setOptions( options );
269271

270-
// if ( isNotEmpty( comment ) ) {
271-
// mappingColumn.setComment( comment );
272-
// }
272+
if ( isNotEmpty( comment ) ) {
273+
mappingColumn.setComment( comment );
274+
}
273275
if ( generatedAs != null ) {
274276
mappingColumn.setGeneratedAs( generatedAs );
275277
}
@@ -318,6 +320,7 @@ protected void initMappingColumn(
318320
}
319321
mappingColumn.setDefaultValue( defaultValue );
320322
mappingColumn.setOptions( options );
323+
mappingColumn.setComment( comment );
321324

322325
if ( writeExpression != null ) {
323326
final int numberOfJdbcParams = StringHelper.count( writeExpression, '?' );
@@ -814,6 +817,7 @@ private static AnnotatedColumn buildColumn(
814817
annotatedColumn.applyGeneratedAs( inferredData, numberOfColumns );
815818
annotatedColumn.applyColumnCheckConstraint( column );
816819
annotatedColumn.applyColumnOptions( column );
820+
annotatedColumn.applyColumnComment(column);
817821
annotatedColumn.applyCheckConstraint( inferredData, numberOfColumns );
818822
annotatedColumn.extractDataFromPropertyData( propertyHolder, inferredData, sourceModelContext );
819823
annotatedColumn.bind();
@@ -1036,6 +1040,12 @@ private void applyColumnOptions(jakarta.persistence.Column column) {
10361040
options = column.options();
10371041
}
10381042

1043+
private void applyColumnComment(jakarta.persistence.Column column) {
1044+
if ( !column.comment().isEmpty() ) {
1045+
comment = column.comment();
1046+
}
1047+
}
1048+
10391049
void setOptions(String options){
10401050
this.options = options;
10411051
}

hibernate-core/src/main/java/org/hibernate/boot/models/annotations/internal/TimeZoneColumnAnnotation.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public class TimeZoneColumnAnnotation implements TimeZoneColumn {
2424
private boolean updatable;
2525
private String columnDefinition;
2626
private String table;
27+
private String options;
28+
private String comment;
2729

2830
/**
2931
* Used in creating dynamic annotation instances (e.g. from XML)
@@ -34,6 +36,8 @@ public TimeZoneColumnAnnotation(SourceModelBuildingContext modelContext) {
3436
this.updatable = true;
3537
this.columnDefinition = "";
3638
this.table = "";
39+
this.options = "";
40+
this.comment = "";
3741
}
3842

3943
/**
@@ -45,6 +49,8 @@ public TimeZoneColumnAnnotation(TimeZoneColumn annotation, SourceModelBuildingCo
4549
this.updatable = annotation.updatable();
4650
this.columnDefinition = annotation.columnDefinition();
4751
this.table = annotation.table();
52+
this.options = annotation.options();
53+
this.comment = annotation.comment();
4854
}
4955

5056
/**
@@ -71,6 +77,8 @@ public TimeZoneColumnAnnotation(AnnotationInstance annotation, SourceModelBuildi
7177
modelContext
7278
);
7379
this.table = extractJandexValue( annotation, HibernateAnnotations.TIME_ZONE_COLUMN, "table", modelContext );
80+
this.options = extractJandexValue( annotation, HibernateAnnotations.TIME_ZONE_COLUMN, "options", modelContext );
81+
this.comment = extractJandexValue( annotation, HibernateAnnotations.TIME_ZONE_COLUMN, "comment", modelContext );
7482
}
7583

7684
@Override
@@ -127,5 +135,21 @@ public void table(String value) {
127135
this.table = value;
128136
}
129137

138+
@Override
139+
public String options() {
140+
return options;
141+
}
142+
143+
public void options(String value) {
144+
this.options = value;
145+
}
130146

147+
@Override
148+
public String comment() {
149+
return comment;
150+
}
151+
152+
public void comment(String value) {
153+
this.comment = value;
154+
}
131155
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package org.hibernate.orm.test.schemaupdate;
2+
3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.nio.file.Files;
6+
import java.time.OffsetTime;
7+
import java.util.EnumSet;
8+
import java.util.Locale;
9+
10+
import org.hibernate.annotations.TimeZoneColumn;
11+
import org.hibernate.annotations.TimeZoneStorage;
12+
import org.hibernate.annotations.TimeZoneStorageType;
13+
import org.hibernate.boot.MetadataSources;
14+
import org.hibernate.boot.registry.StandardServiceRegistry;
15+
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
16+
import org.hibernate.boot.spi.MetadataImplementor;
17+
import org.hibernate.dialect.Dialect;
18+
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
19+
import org.hibernate.tool.hbm2ddl.SchemaExport;
20+
import org.hibernate.tool.schema.TargetType;
21+
22+
import org.hibernate.testing.orm.junit.BaseUnitTest;
23+
import org.hibernate.testing.orm.junit.JiraKey;
24+
import org.hibernate.testing.util.ServiceRegistryUtil;
25+
import org.junit.jupiter.api.AfterEach;
26+
import org.junit.jupiter.api.BeforeEach;
27+
import org.junit.jupiter.api.Test;
28+
29+
import jakarta.persistence.Column;
30+
import jakarta.persistence.Entity;
31+
import jakarta.persistence.Id;
32+
33+
import static org.junit.jupiter.api.Assertions.assertTrue;
34+
35+
@BaseUnitTest
36+
@JiraKey("HHH-17448")
37+
public class TimeZoneColumnTest {
38+
39+
private File output;
40+
private StandardServiceRegistry ssr;
41+
private MetadataImplementor metadata;
42+
43+
@BeforeEach
44+
public void setUp() throws IOException {
45+
output = File.createTempFile( "update_script", ".sql" );
46+
output.deleteOnExit();
47+
ssr = ServiceRegistryUtil.serviceRegistry();
48+
}
49+
50+
@AfterEach
51+
public void tearsDown() {
52+
output.delete();
53+
StandardServiceRegistryBuilder.destroy( ssr );
54+
}
55+
56+
@Test
57+
public void testTableCommentAreCreated() throws Exception {
58+
createSchema( TestEntity.class );
59+
assertTrue(
60+
tableCreationStatementContainsOptions( output, "birthtime_offset_offset", "option_1" ),
61+
"TimeZoneColumn options have not been created "
62+
);
63+
JdbcEnvironment jdbcEnvironment = ssr.getService( JdbcEnvironment.class );
64+
Dialect dialect = jdbcEnvironment.getDialect();
65+
if ( dialect.supportsCommentOn() ) {
66+
assertTrue(
67+
tableCreationStatementContainsComment( output, "birthtime_offset_offset", "This is a comment" ),
68+
"TimeZoneColumn comment have not been created "
69+
);
70+
}
71+
}
72+
73+
private void createSchema(Class... annotatedClasses) {
74+
final MetadataSources metadataSources = new MetadataSources( ssr );
75+
76+
for ( Class c : annotatedClasses ) {
77+
metadataSources.addAnnotatedClass( c );
78+
}
79+
metadata = (MetadataImplementor) metadataSources.buildMetadata();
80+
metadata.orderColumns( false );
81+
metadata.validate();
82+
new SchemaExport()
83+
.setHaltOnError( true )
84+
.setOutputFile( output.getAbsolutePath() )
85+
.setFormat( false )
86+
.createOnly( EnumSet.of( TargetType.SCRIPT ), metadata );
87+
}
88+
89+
private static boolean tableCreationStatementContainsOptions(
90+
File output,
91+
String columnName,
92+
String options) throws Exception {
93+
String[] fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase()
94+
.split( System.lineSeparator() );
95+
for ( int i = 0; i < fileContent.length; i++ ) {
96+
String statement = fileContent[i].toUpperCase( Locale.ROOT );
97+
if ( statement.contains( options.toUpperCase( Locale.ROOT ) ) ) {
98+
return true;
99+
}
100+
}
101+
return false;
102+
}
103+
104+
private static boolean tableCreationStatementContainsComment(
105+
File output,
106+
String columnName,
107+
String comment) throws Exception {
108+
109+
String[] fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase()
110+
.split( System.lineSeparator() );
111+
for ( int i = 0; i < fileContent.length; i++ ) {
112+
String statement = fileContent[i].toUpperCase( Locale.ROOT );
113+
if ( statement.contains( comment.toUpperCase( Locale.ROOT ) ) ) {
114+
return true;
115+
}
116+
}
117+
return false;
118+
}
119+
120+
@Entity(name = "TestEntity")
121+
public static class TestEntity {
122+
123+
@Id
124+
private Long id;
125+
126+
@TimeZoneStorage(TimeZoneStorageType.COLUMN)
127+
@TimeZoneColumn(name = "birthtime_offset_offset", comment = "This is a comment", options = "option_1")
128+
@Column(name = "birthtime_offset")
129+
private OffsetTime offsetTimeColumn;
130+
131+
// @TimeZoneStorage(TimeZoneStorageType.COLUMN)
132+
// @TimeZoneColumn(name = "birthday_zoned_offset")
133+
// @Column(name = "birthday_zoned")
134+
// private ZonedDateTime zonedDateTimeColumn;
135+
136+
}
137+
138+
}
139+

0 commit comments

Comments
 (0)