Skip to content

Commit c46738f

Browse files
committed
HHH-17017 Add test showing 2 possible ways to solve the issue
1 parent 21b62db commit c46738f

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.mapping.enumeratedvalue;
6+
7+
import jakarta.persistence.Column;
8+
import jakarta.persistence.Entity;
9+
import jakarta.persistence.EnumType;
10+
import jakarta.persistence.Enumerated;
11+
import jakarta.persistence.EnumeratedValue;
12+
import jakarta.persistence.Id;
13+
import jakarta.persistence.Table;
14+
import org.hibernate.annotations.JdbcTypeCode;
15+
import org.hibernate.dialect.H2Dialect;
16+
import org.hibernate.dialect.MariaDBDialect;
17+
import org.hibernate.dialect.MySQLDialect;
18+
import org.hibernate.testing.orm.junit.DomainModel;
19+
import org.hibernate.testing.orm.junit.JiraKey;
20+
import org.hibernate.testing.orm.junit.RequiresDialect;
21+
import org.hibernate.testing.orm.junit.SessionFactory;
22+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
23+
import org.hibernate.type.SqlTypes;
24+
import org.junit.jupiter.api.AfterAll;
25+
import org.junit.jupiter.api.Test;
26+
27+
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
28+
29+
@DomainModel(
30+
annotatedClasses = {
31+
EnumAndColumnDefinitionTest.TestEntity.class
32+
}
33+
)
34+
@SessionFactory
35+
@JiraKey("HHH-17017")
36+
@RequiresDialect(MySQLDialect.class)
37+
@RequiresDialect(MariaDBDialect.class)
38+
@RequiresDialect(H2Dialect.class)
39+
public class EnumAndColumnDefinitionTest {
40+
41+
@AfterAll
42+
public static void cleanup(SessionFactoryScope scope) {
43+
scope.getSessionFactory().getSchemaManager().truncateMappedObjects();
44+
}
45+
46+
@Test
47+
public void testFind(SessionFactoryScope scope) {
48+
var id = 1L;
49+
var enumValue = MyEnum.A;
50+
var anotherEnumValue = AnotherMyEnum.B;
51+
var anotherEnumValue2 = AnotherMyEnum.A;
52+
scope.inTransaction(
53+
session ->
54+
session.persist( new TestEntity( id, enumValue, anotherEnumValue, anotherEnumValue2 ) )
55+
);
56+
57+
scope.inSession(
58+
session -> {
59+
var selectMyEnum = session.createNativeQuery(
60+
"select my_enum from test_entity",
61+
String.class
62+
)
63+
.getSingleResult();
64+
assertThat( selectMyEnum ).isEqualTo( "0" );
65+
66+
var selectAnotherMyEnum = session.createNativeQuery(
67+
"select another_my_enum from test_entity",
68+
String.class
69+
)
70+
.getSingleResult();
71+
assertThat( selectAnotherMyEnum ).isEqualTo( "1" );
72+
73+
var selectAnotherMyEnum2 = session.createNativeQuery(
74+
"select another_my_enum_2 from test_entity",
75+
String.class
76+
)
77+
.getSingleResult();
78+
// because the attribute is annotated with @JdbcTypeCode(SqlTypes.VARCHAR)
79+
// the enum string value has been saved
80+
assertThat( selectAnotherMyEnum2 ).isEqualTo( "A" );
81+
}
82+
);
83+
84+
scope.inSession(
85+
session -> {
86+
var testEntity = session.find( TestEntity.class, id );
87+
assertThat( testEntity.myEnum ).isEqualTo( enumValue );
88+
assertThat( testEntity.anotherMyEnum ).isEqualTo( anotherEnumValue );
89+
assertThat( testEntity.anotherMyEnum2 ).isEqualTo( anotherEnumValue2 );
90+
}
91+
);
92+
}
93+
94+
public enum MyEnum {
95+
A( 0 ),
96+
B( 1 );
97+
98+
@EnumeratedValue
99+
final int intValue;
100+
101+
MyEnum(int intValue) {
102+
this.intValue = intValue;
103+
}
104+
}
105+
106+
public enum AnotherMyEnum {
107+
A,
108+
B;
109+
}
110+
111+
@Entity(name = "TestEntity")
112+
@Table(name = "test_entity")
113+
public static class TestEntity {
114+
@Id
115+
Long id;
116+
117+
@Enumerated(value = EnumType.ORDINAL)
118+
@Column(name = "my_enum", columnDefinition = "VARCHAR(255) NOT NULL")
119+
/*
120+
Annotating the enum with @EnumeratedValue permits to store the ordinal value
121+
and retrieve the correct enum value even when the colum is VARCHAR without the
122+
need to specify the @JdbcTypeCode(...).
123+
*/
124+
MyEnum myEnum;
125+
126+
@Enumerated(value = EnumType.ORDINAL)
127+
@Column(name = "another_my_enum", columnDefinition = "VARCHAR(255) NOT NULL")
128+
/*
129+
Without specifying the JdbcTypeCode Hibernate has no clue
130+
of the column being a VARCHAR and being the enum type an
131+
ordinal so a TinyIntJdbcType is used.
132+
Using @JdbcTypeCode(SqlTypes.INTEGER) the ordinal values is saved.
133+
*/
134+
@JdbcTypeCode(SqlTypes.INTEGER)
135+
AnotherMyEnum anotherMyEnum;
136+
137+
@Enumerated(value = EnumType.ORDINAL)
138+
@Column(name = "another_my_enum_2", columnDefinition = "VARCHAR(255) NOT NULL")
139+
/*
140+
Without specifying the JdbcTypeCode Hibernate has no clue
141+
of the column being a VARCHAR and being the enum type an
142+
ordinal so TinyIntJdbcType is used.
143+
Using @JdbcTypeCode(SqlTypes.VARCHAR) the enum string value is saved.
144+
*/
145+
@JdbcTypeCode(SqlTypes.VARCHAR)
146+
AnotherMyEnum anotherMyEnum2;
147+
148+
String name;
149+
150+
public TestEntity() {
151+
152+
}
153+
154+
public TestEntity(Long id, MyEnum myEnum, AnotherMyEnum anotherMyEnum, AnotherMyEnum anotherMyEnum2) {
155+
this.id = id;
156+
this.myEnum = myEnum;
157+
this.anotherMyEnum = anotherMyEnum;
158+
this.anotherMyEnum2 = anotherMyEnum2;
159+
}
160+
}
161+
}

0 commit comments

Comments
 (0)