Hyeonmin Park (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%...
) *updated* an issue
Hibernate ORM (
https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiNjhhMzJkZmI5...
) / Bug (
https://hibernate.atlassian.net/browse/HHH-16838?atlOrigin=eyJpIjoiNjhhMz...
) HHH-16838 (
https://hibernate.atlassian.net/browse/HHH-16838?atlOrigin=eyJpIjoiNjhhMz...
) Cannot use columnDefinition CHAR overriding for enumerated column on MySQL (
https://hibernate.atlassian.net/browse/HHH-16838?atlOrigin=eyJpIjoiNjhhMz...
)
Change By: Hyeonmin Park (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%...
)
The fix for
[
HHH-16498]([https://github.com/hibernate/hibernate-orm/pull/6539|https://...
seems to be making {{columnDefinition}} value ignored.
h2. Reproducer
Mostly copied from { {MySqlExistingEnumColumnValidationTest}}:
{ code:java}package org.hibernate.orm.test.schemavalidation;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.testing.orm.junit.JiraKey;
import org.hibernate.testing.orm.junit.RequiresDialect;
import org.hibernate.testing.transaction.TransactionUtil;
import org.hibernate.tool.hbm2ddl.SchemaValidator;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static jakarta.persistence.GenerationType.IDENTITY;
@JiraKey("HHH-16838")
@RequiresDialect(MySQLDialect.class)
public class MySqlExistingCharAsJavaEnumColumnValidationTest extends
BaseCoreFunctionalTestCase {
private StandardServiceRegistry ssr;
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { EntityE.class };
}
@Before
public void setUp() {
TransactionUtil.doInHibernate( this::sessionFactory, session -> {
session.createNativeQuery( "DROP TABLE IF EXISTS en CASCADE" ).executeUpdate();
session.createNativeQuery(
"CREATE TABLE en (id INTEGER NOT NULL AUTO_INCREMENT"
+ ", sign_position_as_varchar varchar(20)"
+ ", sign_position_as_char char(20)"
+ ", PRIMARY KEY (id))" )
.executeUpdate();
} );
}
@After
public void tearDown() {
TransactionUtil.doInHibernate( this::sessionFactory, session -> {
session.createNativeQuery( "DROP TABLE en CASCADE" ).executeUpdate();
} );
}
@Test
public void testSynonymUsingGroupedSchemaValidator() {
ssr = new StandardServiceRegistryBuilder()
.applySetting( AvailableSettings.HBM2DDL_AUTO, "validate" )
.build();
try {
final MetadataSources metadataSources = new MetadataSources( ssr );
metadataSources.addAnnotatedClass( EntityE.class );
new SchemaValidator().validate( metadataSources.buildMetadata() );
}
finally {
StandardServiceRegistryBuilder.destroy( ssr );
}
}
@Entity(name = "en")
@Table(name = "en")
public static class EntityE {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", nullable = false, updatable = false)
private Integer id;
@Enumerated(EnumType.STRING)
@Column(name = "sign_position_as_varchar")
private SignPosition signPositionAsVarchar;
@Enumerated(EnumType.STRING)
@Column(name = "sign_position_as_char", columnDefinition =
"char(20)")
private SignPosition signPositionAsChar;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public SignPosition getSignPositionAsVarchar() {
return signPositionAsVarchar;
}
public void setSignPositionAsVarchar(SignPosition signPositionAsVarchar) {
this.signPositionAsVarchar = signPositionAsVarchar;
}
public SignPosition getSignPositionAsChar() {
return signPositionAsChar;
}
public void setSignPositionAsChar(SignPosition signPositionAsChar) {
this.signPositionAsChar = signPositionAsChar;
}
}
public enum SignPosition {
AFTER_NO_SPACE, AFTER_WITH_SPACE, BEFORE_NO_SPACE, BEFORE_WITH_SPACE
}
}{code}
h2. Expected result
Since {{signPositionAsChar}} is both declared as char(20) in the SQL query and the
{{columnDefinition}}, the test should be passed.
h2. Actual result
{quote}Schema-validation: wrong column type encountered in column [sign_position_as_char]
in table [en]; found [char (Types#CHAR)], but expecting [char(20) (Types#VARCHAR)]{quote}
h2. Comments
* {{ColumnDefinitions.getSqlType(Column, Metadata)}} returns {{enum
('AFTER_NO_SPACE','AFTER_WITH_SPACE','BEFORE_NO_SPACE','BEFORE_WITH_SPACE')}}
and {{column.getSqlType( metadata )}} properly returns {{char(20)}}. I think there should
exist a check for the pre-configured {{sqlType}}.
* The message of {{SchemaManagementException}} is not matched to
{{ColumnDefinitions.getSqlType(Column, Metadata)}} but since it’s a private method,
{{AbstractSchemaValidator.validateColumnType}} cannot know what’s going on exactly.
* Maybe it’s related to
[
https://hibernate.atlassian.net/browse/HHH-16670|https://hibernate.atlass...]
or
[
https://hibernate.atlassian.net/browse/HHH-16694|https://hibernate.atlass...]
but they say that those are occurring prior to 6.2.5.
I’ve confirmed this issue is not affected until 6.2.2 (via Spring Boot 3.1.0), also 6.2.3
nor 6.2.4 (checked manually by changing {{ext['hibernate.version']}}) so it can be
not related, though.
h2. Naive solution
Didn’t run the full test, but confirmed fixes this issue.
{noformat} .../hibernate/boot/model/internal/AnnotatedColumn.java | 1 +
.../src/main/java/org/hibernate/mapping/Column.java | 9 +++++++++
.../tool/schema/internal/ColumnDefinitions.java | 3 +++
3 files changed, 13 insertions(+)
diff --git
a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedColumn.java
b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedColumn.java
index 02beed2fff..1eaca964df 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedColumn.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedColumn.java
@@ -294,6 +294,7 @@ public class AnnotatedColumn {
mappingColumn.setResolvedCustomRead( readExpression );
mappingColumn.setCustomWrite( writeExpression );
+ mappingColumn.setColumnDefinitionConfigured( sqlType != null );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Column.java
b/hibernate-core/src/main/java/org/hibernate/mapping/Column.java
index dde3b634d3..88debbe606 100644
--- a/hibernate-core/src/main/java/org/hibernate/mapping/Column.java
+++ b/hibernate-core/src/main/java/org/hibernate/mapping/Column.java
@@ -69,6 +69,7 @@ public class Column implements Selectable, Serializable, Cloneable,
ColumnTypeIn
private Size columnSize;
private String specializedTypeDeclaration;
private java.util.List<CheckConstraint> checkConstraints = new ArrayList<>();
+ private boolean columnDefinitionConfigured;
public Column() {
}
@@ -502,6 +503,14 @@ public class Column implements Selectable, Serializable, Cloneable,
ColumnTypeIn
return unmodifiableList( checkConstraints );
}
+ public void setColumnDefinitionConfigured(boolean columnDefinitionConfigured) {
+ this.columnDefinitionConfigured = columnDefinitionConfigured;
+ }
+
+ public boolean isColumnDefinitionConfigured() {
+ return columnDefinitionConfigured;
+ }
+
@Deprecated(since = "6.2")
public String getCheckConstraint() {
if ( checkConstraints.isEmpty() ) {
diff --git
a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/ColumnDefinitions.java
b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/ColumnDefinitions.java
index 16dbb60b32..3ad4912a42 100644
---
a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/ColumnDefinitions.java
+++
b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/ColumnDefinitions.java
@@ -44,6 +44,9 @@ class ColumnDefinitions {
}
private static String getSqlType(Column column, Metadata metadata) {
+ if ( column.isColumnDefinitionConfigured() ) {
+ return column.getSqlType( metadata );
+ }
if ( column.hasSpecializedTypeDeclaration() ) {
return column.getSpecializedTypeDeclaration();
}{noformat}
(
https://hibernate.atlassian.net/browse/HHH-16838#add-comment?atlOrigin=ey...
) Add Comment (
https://hibernate.atlassian.net/browse/HHH-16838#add-comment?atlOrigin=ey...
)
Get Jira notifications on your phone! Download the Jira Cloud app for Android (
https://play.google.com/store/apps/details?id=com.atlassian.android.jira....
) or iOS (
https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=Em...
) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100227- sha1:d138f7b )