HHH-18055 Support for JPA 3.2 table comment

This commit is contained in:
Andrea Boriero 2024-05-06 18:06:20 +02:00 committed by Steve Ebersole
parent fd30841c33
commit 68b8ae3f22
6 changed files with 267 additions and 5 deletions

View File

@ -2586,8 +2586,10 @@ public abstract class CollectionBinder {
} );
property.forEachAnnotationUsage(
jakarta.persistence.JoinTable.class,
(usage) ->
TableBinder.addTableCheck( collectionTable, usage.findAttributeValue( "check" ) )
(usage) -> {
TableBinder.addTableCheck( collectionTable, usage.findAttributeValue( "check" ) );
TableBinder.addTableComment( collectionTable, usage.getString( "comment" ) );
}
);
}

View File

@ -450,6 +450,7 @@ public class EntityBinder {
final Table table = persistentClass.getTable();
TableBinder.addJpaIndexes( table, jpaTableUsage.getList( "indexes" ), context );
TableBinder.addTableCheck( table, jpaTableUsage.findAttributeValue( "check" ) );
TableBinder.addTableComment( table, jpaTableUsage.getString( "comment" ) );
}
final InFlightMetadataCollector.EntityTableXref entityTableXref = context
@ -2179,7 +2180,9 @@ public class EntityBinder {
joinTable.getList( "joinColumns" ),
joinTable.getList( "uniqueConstraints" )
);
TableBinder.addTableCheck( join.getTable(), joinTable.findAttributeValue( "check" ));
final Table table = join.getTable();
TableBinder.addTableCheck( table, joinTable.findAttributeValue( "check" ) );
TableBinder.addTableComment( table, joinTable.getString( "comment" ) );
return join;
}
@ -2197,6 +2200,7 @@ public class EntityBinder {
final Table table = join.getTable();
new IndexBinder( context ).bindIndexes( table, secondaryTable.getList( "indexes" ) );
TableBinder.addTableCheck( table, secondaryTable.findAttributeValue( "check" ) );
TableBinder.addTableComment( table, secondaryTable.getString( "comment" ) );
return join;
}

View File

@ -23,6 +23,7 @@ import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.dialect.Dialect;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.mapping.Any;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.mapping.CheckConstraint;
import org.hibernate.mapping.Collection;
@ -888,6 +889,12 @@ public class TableBinder {
}
}
static void addTableComment(Table table, String comment) {
if ( StringHelper.isNotEmpty( comment ) ) {
table.setComment( comment );
}
}
public void setDefaultName(
String ownerClassName,
String ownerEntity,

View File

@ -0,0 +1,153 @@
package org.hibernate.orm.test.schemaupdate.tablecomment;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.EnumSet;
import java.util.Locale;
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.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.schema.TargetType;
import org.hibernate.testing.orm.junit.BaseUnitTest;
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.orm.junit.JiraKey;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
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 static org.junit.jupiter.api.Assertions.assertTrue;
@JiraKey("HHH-18055")
@BaseUnitTest
@RequiresDialectFeature( feature = DialectFeatureChecks.SupportsCommentOn.class)
public class JpaTableCommentTest {
static final String TABLE_NAME = "PRIMARY_TABLE";
static final String TABLE_COMMENT = "This is the primary table";
static final String SECONDARY_TABLE_NAME = "SECOND_TABLE";
static final String SECONDARY_TABLE_COMMENT = "This is the secondary table";
static final String JOIN_TABLE_NAME = "JOIN_TABLE";
static final String JOIN_TABLE_COMMENT = "This is the join table";
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(
tableCreationStatementContainsComment( output, TABLE_NAME, TABLE_COMMENT ),
"Table " + TABLE_NAME + " comment has not been created "
);
assertTrue(
tableCreationStatementContainsComment( output, SECONDARY_TABLE_NAME, SECONDARY_TABLE_COMMENT ),
"SecondaryTable " + SECONDARY_TABLE_NAME + " comment has not been created "
);
assertTrue(
tableCreationStatementContainsComment( output, JOIN_TABLE_NAME, JOIN_TABLE_COMMENT ),
"Join Table " + JOIN_TABLE_NAME + " comment has not been created "
);
}
@Test
public void testXmlMAppingTableCommentAreCreated() throws Exception {
createSchema( "org/hibernate/orm/test/schemaupdate/tablecomment/TestEntity.xml" );
assertTrue(
tableCreationStatementContainsComment( output, TABLE_NAME, TABLE_COMMENT ),
"Table " + TABLE_NAME + " comment has not been created "
);
assertTrue(
tableCreationStatementContainsComment( output, JOIN_TABLE_NAME, JOIN_TABLE_COMMENT ),
"Join Table " + JOIN_TABLE_NAME + " comment has not been created "
);
assertTrue(
tableCreationStatementContainsComment( output, SECONDARY_TABLE_NAME, SECONDARY_TABLE_COMMENT ),
"SecondaryTable " + SECONDARY_TABLE_NAME + " comment has not been created "
);
}
private boolean tableCreationStatementContainsComment(
File output,
String tableName,
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 ( !metadata.getDatabase().getDialect().getTableComment( "" ).isEmpty() ) {
if ( statement.contains( "CREATE TABLE " + tableName.toUpperCase( Locale.ROOT ) ) ) {
if ( statement.contains( comment.toUpperCase( Locale.ROOT ) ) ) {
return true;
}
}
}
else if ( statement.contains( "COMMENT ON TABLE " + tableName.toUpperCase( Locale.ROOT ) ) ) {
if ( statement.contains( comment.toUpperCase( Locale.ROOT ) ) ) {
return true;
}
}
}
return false;
}
private void createSchema(String... xmlMapping) {
final MetadataSources metadataSources = new MetadataSources( ssr );
for ( String xml : xmlMapping ) {
metadataSources.addResource( xml );
}
metadata = (MetadataImplementor) metadataSources.buildMetadata();
metadata.orderColumns( false );
metadata.validate();
new SchemaExport()
.setHaltOnError( true )
.setOutputFile( output.getAbsolutePath() )
.setFormat( false )
.create( EnumSet.of( TargetType.SCRIPT ), metadata );
}
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 )
.create( EnumSet.of( TargetType.SCRIPT ), metadata );
}
}

View File

@ -0,0 +1,69 @@
package org.hibernate.orm.test.schemaupdate.tablecomment;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.SecondaryTable;
import jakarta.persistence.Table;
@Entity
@Table(
name = JpaTableCommentTest.TABLE_NAME,
comment = JpaTableCommentTest.TABLE_COMMENT
)
@SecondaryTable(
name = JpaTableCommentTest.SECONDARY_TABLE_NAME,
comment = JpaTableCommentTest.SECONDARY_TABLE_COMMENT
)
public class TestEntity {
@Id
private Long id;
@Column(name = "NAME_COLUMN")
private String name;
@Column(name = "SECOND_NAME", table = JpaTableCommentTest.SECONDARY_TABLE_NAME)
private String secondName;
@ManyToOne(fetch = FetchType.LAZY)
@JoinTable(
name = JpaTableCommentTest.JOIN_TABLE_NAME,
comment = JpaTableCommentTest.JOIN_TABLE_COMMENT
)
private TestEntity testEntity;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSecondName() {
return secondName;
}
public void setSecondName(String secondName) {
this.secondName = secondName;
}
public TestEntity getTestEntity() {
return testEntity;
}
public void setTestEntity(TestEntity testEntity) {
this.testEntity = testEntity;
}
}

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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>.
-->
<entity-mappings xmlns="http://www.hibernate.org/xsd/orm/mapping" version="3.2">
<package>org.hibernate.orm.test.schemaupdate.tablecomment</package>
<entity class="TestEntity" metadata-complete="true">
<table name="PRIMARY_TABLE" comment="This is the primary table"/>
<secondary-table name="SECOND_TABLE" comment="This is the secondary table"/>
<attributes>
<id name="id"/>
<basic name="name">
<column name="NAME_COLUMN"/>
</basic>
<basic name="secondName" >
<column name="secondName" table="SECOND_TABLE"/>
</basic>
<many-to-one name="testEntity">
<join-table name="JOIN_TABLE"
comment="This is the join table"/>
</many-to-one>
</attributes>
</entity>
</entity-mappings>