Skip to content

Commit 3ca07ab

Browse files
committed
DATAJPA-655 - Added AttributeConverters for ThreeTen backport library.
We now ship JPA 2.1 AttributeConverters for the ThreeTen back port library [0] similarly to the one we provide for JSR-310. [0] http://www.threeten.org/threetenbp
1 parent 7f18bee commit 3ca07ab

File tree

7 files changed

+257
-47
lines changed

7 files changed

+257
-47
lines changed

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,13 @@
137137
<optional>true</optional>
138138
</dependency>
139139

140+
<dependency>
141+
<groupId>org.threeten</groupId>
142+
<artifactId>threetenbp</artifactId>
143+
<version>${threetenbp}</version>
144+
<optional>true</optional>
145+
</dependency>
146+
140147
<!-- Persistence providers -->
141148

142149
<dependency>
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.jpa.domain.support;
17+
18+
import java.util.Date;
19+
20+
import javax.persistence.AttributeConverter;
21+
import javax.persistence.Converter;
22+
23+
import org.springframework.data.convert.Jsr310BackPortConverters.DateToInstantConverter;
24+
import org.springframework.data.convert.Jsr310BackPortConverters.DateToLocalDateConverter;
25+
import org.springframework.data.convert.Jsr310BackPortConverters.DateToLocalDateTimeConverter;
26+
import org.springframework.data.convert.Jsr310BackPortConverters.DateToLocalTimeConverter;
27+
import org.springframework.data.convert.Jsr310BackPortConverters.InstantToDateConverter;
28+
import org.springframework.data.convert.Jsr310BackPortConverters.LocalDateTimeToDateConverter;
29+
import org.springframework.data.convert.Jsr310BackPortConverters.LocalDateToDateConverter;
30+
import org.springframework.data.convert.Jsr310BackPortConverters.LocalTimeToDateConverter;
31+
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
32+
import org.threeten.bp.Instant;
33+
import org.threeten.bp.LocalDate;
34+
import org.threeten.bp.LocalDateTime;
35+
import org.threeten.bp.LocalTime;
36+
37+
/**
38+
* JPA 2.1 converters to turn ThreeTen back port types into legacy {@link Date}s. To activate these converters make sure
39+
* your persistence provider detects them by including this class in the list of mapped classes. In Spring environments,
40+
* you can simply register the package of this class (i.e. {@code org.springframework.data.jpa.domain.support}) as
41+
* package to be scanned on e.g. the {@link LocalContainerEntityManagerFactoryBean}.
42+
*
43+
* @author Oliver Gierke
44+
* @see http://www.threeten.org/threetenbp
45+
*/
46+
public class Jsr310BackPortJpaConverters {
47+
48+
@Converter(autoApply = true)
49+
public static class LocalDateConverter implements AttributeConverter<LocalDate, Date> {
50+
51+
@Override
52+
public Date convertToDatabaseColumn(LocalDate date) {
53+
return LocalDateToDateConverter.INSTANCE.convert(date);
54+
}
55+
56+
@Override
57+
public LocalDate convertToEntityAttribute(Date date) {
58+
return DateToLocalDateConverter.INSTANCE.convert(date);
59+
}
60+
}
61+
62+
@Converter(autoApply = true)
63+
public static class LocalTimeConverter implements AttributeConverter<LocalTime, Date> {
64+
65+
@Override
66+
public Date convertToDatabaseColumn(LocalTime time) {
67+
return LocalTimeToDateConverter.INSTANCE.convert(time);
68+
}
69+
70+
@Override
71+
public LocalTime convertToEntityAttribute(Date date) {
72+
return DateToLocalTimeConverter.INSTANCE.convert(date);
73+
}
74+
}
75+
76+
@Converter(autoApply = true)
77+
public static class LocalDateTimeConverter implements AttributeConverter<LocalDateTime, Date> {
78+
79+
@Override
80+
public Date convertToDatabaseColumn(LocalDateTime date) {
81+
return LocalDateTimeToDateConverter.INSTANCE.convert(date);
82+
}
83+
84+
@Override
85+
public LocalDateTime convertToEntityAttribute(Date date) {
86+
return DateToLocalDateTimeConverter.INSTANCE.convert(date);
87+
}
88+
}
89+
90+
@Converter(autoApply = true)
91+
public static class InstantConverter implements AttributeConverter<Instant, Date> {
92+
93+
@Override
94+
public Date convertToDatabaseColumn(Instant instant) {
95+
return InstantToDateConverter.INSTANCE.convert(instant);
96+
}
97+
98+
@Override
99+
public Instant convertToEntityAttribute(Date date) {
100+
return DateToInstantConverter.INSTANCE.convert(date);
101+
}
102+
}
103+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.jpa.domain.support;
17+
18+
import javax.persistence.AttributeConverter;
19+
import javax.sql.DataSource;
20+
21+
import org.junit.runner.RunWith;
22+
import org.springframework.context.annotation.Bean;
23+
import org.springframework.context.annotation.Configuration;
24+
import org.springframework.data.jpa.domain.sample.User;
25+
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
26+
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
27+
import org.springframework.orm.jpa.JpaTransactionManager;
28+
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
29+
import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
30+
import org.springframework.orm.jpa.vendor.Database;
31+
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
32+
import org.springframework.test.context.ContextConfiguration;
33+
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
34+
import org.springframework.transaction.PlatformTransactionManager;
35+
import org.springframework.transaction.annotation.Transactional;
36+
37+
/**
38+
* Base class for integration tests for JPA 2.1 {@link AttributeConverter} integration.
39+
*
40+
* @author Oliver Gierke
41+
*/
42+
@RunWith(SpringJUnit4ClassRunner.class)
43+
@ContextConfiguration
44+
@Transactional
45+
public abstract class AbstractAttributeConverterIntegrationTests {
46+
47+
@Configuration
48+
static class Config {
49+
50+
@Bean
51+
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
52+
53+
AbstractJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
54+
vendorAdapter.setDatabase(Database.HSQL);
55+
vendorAdapter.setGenerateDdl(true);
56+
57+
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
58+
factory.setDataSource(dataSource());
59+
factory.setPackagesToScan(getClass().getPackage().getName(), User.class.getPackage().getName());
60+
factory.setJpaVendorAdapter(vendorAdapter);
61+
62+
return factory;
63+
}
64+
65+
public @Bean PlatformTransactionManager transactionManager() {
66+
return new JpaTransactionManager();
67+
}
68+
69+
public @Bean DataSource dataSource() {
70+
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).build();
71+
}
72+
}
73+
}

src/test/java/org/springframework/data/jpa/domain/support/DateTimeSample.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,9 @@ public class DateTimeSample {
3535
LocalDate localDate;
3636
LocalTime localTime;
3737
LocalDateTime localDateTime;
38+
39+
org.threeten.bp.Instant bpInstant;
40+
org.threeten.bp.LocalDate bpLocalDate;
41+
org.threeten.bp.LocalTime bpLocalTime;
42+
org.threeten.bp.LocalDateTime bpLocalDateTime;
3843
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright 2014 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.jpa.domain.support;
17+
18+
import static org.hamcrest.CoreMatchers.*;
19+
import static org.junit.Assert.*;
20+
import static org.junit.Assume.*;
21+
import static org.springframework.data.jpa.support.EntityManagerTestUtils.*;
22+
23+
import javax.persistence.EntityManager;
24+
import javax.persistence.PersistenceContext;
25+
26+
import org.junit.Test;
27+
import org.threeten.bp.Instant;
28+
import org.threeten.bp.LocalDate;
29+
import org.threeten.bp.LocalDateTime;
30+
import org.threeten.bp.LocalTime;
31+
32+
/**
33+
* Integration tests for {@link Jsr310BackPortJpaConverters}.
34+
*
35+
* @author Oliver Gierke
36+
*/
37+
public class Jsr310BackPortJpaConvertersIntegrationTests extends AbstractAttributeConverterIntegrationTests {
38+
39+
@PersistenceContext EntityManager em;
40+
41+
/**
42+
* @see DATAJPA-650
43+
*/
44+
@Test
45+
public void usesJsr310BackPortJpaConverters() {
46+
47+
assumeTrue(currentEntityManagerIsAJpa21EntityManager(em));
48+
49+
DateTimeSample sample = new DateTimeSample();
50+
51+
sample.bpInstant = Instant.now();
52+
sample.bpLocalDate = LocalDate.now();
53+
sample.bpLocalTime = LocalTime.now();
54+
sample.bpLocalDateTime = LocalDateTime.now();
55+
56+
em.persist(sample);
57+
em.clear();
58+
59+
DateTimeSample result = em.find(DateTimeSample.class, sample.id);
60+
61+
assertThat(result, is(notNullValue()));
62+
assertThat(result.bpInstant, is(sample.bpInstant));
63+
assertThat(result.bpLocalDate, is(sample.bpLocalDate));
64+
assertThat(result.bpLocalTime, is(sample.bpLocalTime));
65+
assertThat(result.bpLocalDateTime, is(sample.bpLocalDateTime));
66+
}
67+
}

src/test/java/org/springframework/data/jpa/domain/support/Jsr310JpaConvertersIntegrationTests.java

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -27,61 +27,15 @@
2727

2828
import javax.persistence.EntityManager;
2929
import javax.persistence.PersistenceContext;
30-
import javax.sql.DataSource;
3130

3231
import org.junit.Test;
33-
import org.junit.runner.RunWith;
34-
import org.springframework.context.annotation.Bean;
35-
import org.springframework.context.annotation.Configuration;
36-
import org.springframework.data.jpa.domain.sample.User;
37-
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
38-
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
39-
import org.springframework.orm.jpa.JpaTransactionManager;
40-
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
41-
import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
42-
import org.springframework.orm.jpa.vendor.Database;
43-
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
44-
import org.springframework.test.context.ContextConfiguration;
45-
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
46-
import org.springframework.transaction.PlatformTransactionManager;
47-
import org.springframework.transaction.annotation.Transactional;
4832

4933
/**
5034
* Integration tests for {@link Jsr310JpaConverters}.
5135
*
5236
* @author Oliver Gierke
5337
*/
54-
@RunWith(SpringJUnit4ClassRunner.class)
55-
@ContextConfiguration
56-
@Transactional
57-
public class Jsr310JpaConvertersIntegrationTests {
58-
59-
@Configuration
60-
static class Config {
61-
62-
@Bean
63-
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
64-
65-
AbstractJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
66-
vendorAdapter.setDatabase(Database.HSQL);
67-
vendorAdapter.setGenerateDdl(true);
68-
69-
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
70-
factory.setDataSource(dataSource());
71-
factory.setPackagesToScan(getClass().getPackage().getName(), User.class.getPackage().getName());
72-
factory.setJpaVendorAdapter(vendorAdapter);
73-
74-
return factory;
75-
}
76-
77-
public @Bean PlatformTransactionManager transactionManager() {
78-
return new JpaTransactionManager();
79-
}
80-
81-
public @Bean DataSource dataSource() {
82-
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).build();
83-
}
84-
}
38+
public class Jsr310JpaConvertersIntegrationTests extends AbstractAttributeConverterIntegrationTests {
8539

8640
@PersistenceContext EntityManager em;
8741

template.mf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Import-Template:
2121
org.springframework.*;version="${spring:[=.=.=.=,+1.1.0)}",
2222
org.springframework.beans.factory.aspectj;version="${spring:[=.=.=.=,+1.1.0)}";resolution:=optional,
2323
org.springframework.data.*;version="${springdata.commons:[=.=.=.=,+1.0.0)}",
24+
org.threeten.bp.*;version="${threetenbp:[=.=.=,+1.0.0)}";resolution:=optional,
2425
org.w3c.*;version="0.0.0"
2526
Import-Package: org.aspectj.lang;version="${aspectj:[=.=.=,+1.0.0)}";resolution:=optional,
2627
org.aspectj.runtime.reflect;version="${aspectj:[=.=.=,+1.0.0)}";resolution:=optional,

0 commit comments

Comments
 (0)