Skip to content

Commit 049d151

Browse files
committed
HHH-15605 Fix parameter binding of converted TemporalJavaType
1 parent 149da82 commit 049d151

File tree

2 files changed

+114
-2
lines changed

2 files changed

+114
-2
lines changed

hibernate-core/src/main/java/org/hibernate/query/internal/BindingTypeHelper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,12 @@ public JdbcMapping resolveBindType(
6464
Object value,
6565
JdbcMapping baseType,
6666
TypeConfiguration typeConfiguration) {
67-
if ( value == null || !( baseType.getJavaTypeDescriptor() instanceof TemporalJavaType<?> ) ) {
67+
if ( value == null || !( baseType.getJdbcJavaType() instanceof TemporalJavaType<?> ) ) {
6868
return baseType;
6969
}
7070

7171
final Class<?> javaType = value.getClass();
72-
final TemporalType temporalType = ( (TemporalJavaType<?>) baseType.getJavaTypeDescriptor() ).getPrecision();
72+
final TemporalType temporalType = ( (TemporalJavaType<?>) baseType.getJdbcJavaType() ).getPrecision();
7373
switch ( temporalType ) {
7474
case TIMESTAMP: {
7575
return (JdbcMapping) resolveTimestampTemporalTypeVariant( javaType, (BindableType<?>) baseType, typeConfiguration );
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.orm.test.jpa.convert;
8+
9+
import java.time.ZoneId;
10+
import java.time.ZonedDateTime;
11+
import java.time.format.DateTimeFormatter;
12+
13+
import org.hibernate.testing.TestForIssue;
14+
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
15+
import org.hibernate.testing.orm.junit.Jpa;
16+
import org.junit.jupiter.api.Test;
17+
18+
import jakarta.persistence.AttributeConverter;
19+
import jakarta.persistence.Convert;
20+
import jakarta.persistence.Entity;
21+
import jakarta.persistence.GeneratedValue;
22+
import jakarta.persistence.Id;
23+
24+
import static org.junit.jupiter.api.Assertions.assertEquals;
25+
26+
@Jpa(
27+
annotatedClasses = ZonedDateTimeConverterTest.JavaTimeBean.class
28+
)
29+
public class ZonedDateTimeConverterTest {
30+
31+
@Test
32+
@TestForIssue(jiraKey = "HHH-15605")
33+
public void testConvertedTemporalJavaType(EntityManagerFactoryScope scope) {
34+
// Because some databases do not support millisecond values in timestamps, we clear it here.
35+
// This will serve sufficient for our test to verify that the retrieved values match persisted.
36+
ZonedDateTime today = ZonedDateTime.now( ZonedDateTimeConverter.BERLIN ).withNano( 0 );
37+
38+
// persist the record.
39+
JavaTimeBean testEntity = scope.fromTransaction( entityManager -> {
40+
JavaTimeBean javaTime = new JavaTimeBean();
41+
javaTime.setUpdated( today.minusDays( 14L ) );
42+
entityManager.persist( javaTime );
43+
return javaTime;
44+
} );
45+
46+
// retrieve the record and verify values.
47+
scope.inTransaction( entityManager -> {
48+
JavaTimeBean demo = entityManager.createQuery(
49+
"select d1_0 from JavaTimeBean d1_0 where d1_0.updated<?1", JavaTimeBean.class )
50+
.setParameter( 1, today )
51+
.getSingleResult();
52+
53+
assertEquals( testEntity.getUpdated(), demo.getUpdated() );
54+
} );
55+
}
56+
57+
@Entity(name = "JavaTimeBean")
58+
public static class JavaTimeBean {
59+
@Id
60+
@GeneratedValue
61+
private Integer id;
62+
63+
@Convert(converter = ZonedDateTimeConverter.class)
64+
private ZonedDateTime updated;
65+
66+
public Integer getId() {
67+
return id;
68+
}
69+
70+
public void setId(Integer id) {
71+
this.id = id;
72+
}
73+
74+
public ZonedDateTime getUpdated() {
75+
return updated;
76+
}
77+
78+
public void setUpdated(ZonedDateTime updated) {
79+
this.updated = updated;
80+
}
81+
}
82+
83+
public static class ZonedDateTimeConverter implements AttributeConverter<ZonedDateTime, String> {
84+
85+
public static final ZoneId BERLIN = ZoneId.of( "Europe/Berlin");
86+
87+
@Override
88+
public String convertToDatabaseColumn(ZonedDateTime localDateTime) {
89+
90+
if (localDateTime == null) {
91+
92+
return null;
93+
}
94+
95+
String bla = localDateTime.withZoneSameInstant(ZonedDateTimeConverter.BERLIN)
96+
.format( DateTimeFormatter.ISO_OFFSET_DATE_TIME);
97+
return bla;
98+
}
99+
100+
@Override
101+
public ZonedDateTime convertToEntityAttribute(String databaseString) {
102+
103+
if (databaseString == null) {
104+
105+
return null;
106+
}
107+
108+
return ZonedDateTime.parse(databaseString, DateTimeFormatter.ISO_OFFSET_DATE_TIME)
109+
.withZoneSameInstant(ZonedDateTimeConverter.BERLIN);
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)