Skip to content

Commit 458b2dc

Browse files
committed
HHH-8842 - Hibernate can't handle JodaTime Converters result (possible bug)
(cherry picked from commit 6fb5a89)
1 parent 5620744 commit 458b2dc

File tree

3 files changed

+140
-3
lines changed

3 files changed

+140
-3
lines changed

hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/JdbcTypeJavaClassMappings.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import java.math.BigDecimal;
2727
import java.sql.Blob;
2828
import java.sql.Clob;
29-
import java.sql.Date;
3029
import java.sql.Ref;
3130
import java.sql.Struct;
3231
import java.sql.Time;
@@ -108,7 +107,7 @@ private static ConcurrentHashMap<Class, Integer> buildJdbcJavaClassMappings() {
108107
jdbcJavaClassMappings.put( Float.class, Types.REAL );
109108
jdbcJavaClassMappings.put( Double.class, Types.DOUBLE );
110109
jdbcJavaClassMappings.put( byte[].class, Types.LONGVARBINARY );
111-
jdbcJavaClassMappings.put( Date.class, Types.DATE );
110+
jdbcJavaClassMappings.put( java.sql.Date.class, Types.DATE );
112111
jdbcJavaClassMappings.put( Time.class, Types.TIME );
113112
jdbcJavaClassMappings.put( Timestamp.class, Types.TIMESTAMP );
114113
jdbcJavaClassMappings.put( Blob.class, Types.BLOB );
@@ -123,7 +122,7 @@ private static ConcurrentHashMap<Class, Integer> buildJdbcJavaClassMappings() {
123122
jdbcJavaClassMappings.put( char[].class, Types.VARCHAR );
124123
jdbcJavaClassMappings.put( Character[].class, Types.VARCHAR );
125124
jdbcJavaClassMappings.put( Byte[].class, Types.LONGVARBINARY );
126-
jdbcJavaClassMappings.put( Date.class, Types.TIMESTAMP );
125+
jdbcJavaClassMappings.put( java.util.Date.class, Types.TIMESTAMP );
127126
jdbcJavaClassMappings.put( Calendar.class, Types.TIMESTAMP );
128127

129128
return jdbcJavaClassMappings;

hibernate-entitymanager/hibernate-entitymanager.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ dependencies {
3232
// for testing stored procedure support
3333
testCompile( libraries.derby )
3434

35+
testCompile( 'joda-time:joda-time:2.3' )
36+
3537
hibernateJpaModelGenTool( project( ':hibernate-jpamodelgen' ) )
3638
}
3739

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
5+
* indicated by the @author tags or express copyright attribution
6+
* statements applied by the authors. All third-party contributions are
7+
* distributed under license by Red Hat Inc.
8+
*
9+
* This copyrighted material is made available to anyone wishing to use, modify,
10+
* copy, or redistribute it subject to the terms and conditions of the GNU
11+
* Lesser General Public License, as published by the Free Software Foundation.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15+
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
16+
* for more details.
17+
*
18+
* You should have received a copy of the GNU Lesser General Public License
19+
* along with this distribution; if not, write to:
20+
* Free Software Foundation, Inc.
21+
* 51 Franklin Street, Fifth Floor
22+
* Boston, MA 02110-1301 USA
23+
*/
24+
package org.hibernate.jpa.test.convert;
25+
26+
import java.net.MalformedURLException;
27+
import java.util.Arrays;
28+
import java.util.Date;
29+
import java.util.HashMap;
30+
import java.util.List;
31+
import java.util.Map;
32+
import javax.persistence.AttributeConverter;
33+
import javax.persistence.Column;
34+
import javax.persistence.Convert;
35+
import javax.persistence.Entity;
36+
import javax.persistence.EntityManager;
37+
import javax.persistence.EntityManagerFactory;
38+
import javax.persistence.Id;
39+
40+
import org.hibernate.cfg.AvailableSettings;
41+
import org.hibernate.engine.spi.SessionFactoryImplementor;
42+
import org.hibernate.jpa.boot.spi.Bootstrap;
43+
import org.hibernate.jpa.test.PersistenceUnitDescriptorAdapter;
44+
import org.hibernate.persister.entity.EntityPersister;
45+
import org.hibernate.type.Type;
46+
import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
47+
48+
import org.hibernate.testing.TestForIssue;
49+
50+
import org.junit.Test;
51+
52+
import org.joda.time.LocalDate;
53+
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
54+
import static org.junit.Assert.assertEquals;
55+
56+
/**
57+
* @author Steve Ebersole
58+
*/
59+
@TestForIssue( jiraKey = "HHH-8842" )
60+
public class BasicJodaTimeConversionTest {
61+
static int callsToConverter = 0;
62+
63+
public static class JodaLocalDateConverter implements AttributeConverter<LocalDate, Date> {
64+
public Date convertToDatabaseColumn(LocalDate localDate) {
65+
callsToConverter++;
66+
return localDate.toDate();
67+
}
68+
69+
public LocalDate convertToEntityAttribute(Date date) {
70+
callsToConverter++;
71+
return LocalDate.fromDateFields( date );
72+
}
73+
}
74+
75+
@Entity( name = "TheEntity" )
76+
public static class TheEntity {
77+
@Id
78+
public Integer id;
79+
@Convert( converter = JodaLocalDateConverter.class )
80+
public LocalDate theDate;
81+
82+
public TheEntity() {
83+
}
84+
85+
public TheEntity(Integer id, LocalDate theDate) {
86+
this.id = id;
87+
this.theDate = theDate;
88+
}
89+
}
90+
91+
@Test
92+
public void testSimpleConvertUsage() throws MalformedURLException {
93+
final PersistenceUnitDescriptorAdapter pu = new PersistenceUnitDescriptorAdapter() {
94+
@Override
95+
public List<String> getManagedClassNames() {
96+
return Arrays.asList( TheEntity.class.getName() );
97+
}
98+
};
99+
100+
final Map settings = new HashMap();
101+
settings.put( AvailableSettings.HBM2DDL_AUTO, "create-drop" );
102+
103+
EntityManagerFactory emf = Bootstrap.getEntityManagerFactoryBuilder( pu, settings ).build();
104+
final EntityPersister ep = emf.unwrap( SessionFactoryImplementor.class ).getEntityPersister( TheEntity.class.getName() );
105+
final Type theDatePropertyType = ep.getPropertyType( "theDate" );
106+
final AttributeConverterTypeAdapter type = assertTyping( AttributeConverterTypeAdapter.class, theDatePropertyType );
107+
assertTyping( JodaLocalDateConverter.class, type.getAttributeConverter() );
108+
109+
try {
110+
EntityManager em = emf.createEntityManager();
111+
em.getTransaction().begin();
112+
em.persist( new TheEntity( 1, new LocalDate() ) );
113+
em.getTransaction().commit();
114+
em.close();
115+
116+
assertEquals( 1, callsToConverter );
117+
118+
em = emf.createEntityManager();
119+
em.getTransaction().begin();
120+
em.find( TheEntity.class, 1 );
121+
em.getTransaction().commit();
122+
em.close();
123+
124+
assertEquals( 2, callsToConverter );
125+
126+
em = emf.createEntityManager();
127+
em.getTransaction().begin();
128+
em.createQuery( "delete TheEntity" ).executeUpdate();
129+
em.getTransaction().commit();
130+
em.close();
131+
}
132+
finally {
133+
emf.close();
134+
}
135+
}
136+
}

0 commit comments

Comments
 (0)