Learn to map Java temporal classes (date/time) to SQL types while storing the time-based values in the database. We will be learning to map the Java classes from java.time
package.
We are not covering the legacy classes such as java.util.Date
, java.util.Calendar
and classes from java.sql
package as they are obsolete now and we should move to updated versions if we have not already.
1. Project Setup
To demonstrate the temporal mappings, we are using Hibernate 6 and in-memory database H2.
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.0.0.Final</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.212</version>
<scope>test</scope>
</dependency>
Next, we need to setup the SessionFactory for connecting to the database.
2. Mapping Java Types to JDBC Types
In SQL, we have primarily 3 types to store date-time information:
DATE
TIME
TIMESTAMP
There may be a few more types based on the database support.
TIME_WITH_TIMEZONE
TIMESTAMP_WITH_TIMEZONE
TIMESTAMP_UTC
INTERVAL_SECOND
On the other hand, since Java 8, we have the following java.time
classes that can be mapped directly to SQL types:
Java Type | JDBC Type |
---|---|
LocalTime | TIME |
OffsetTime | TIME or TIME_WITH_TIMEZONE |
LocalDate | DATE |
LocalDateTime | TIMESTAMP |
ZonedDateTime | TIMESTAMP or TIMESTAMP_WITH_TIMEZONE |
OffsetDateTime | TIMESTAMP or TIMESTAMP_WITH_TIMEZONE |
Instant | TIMESTAMP_UTC |
Duration | INTERVAL_SECOND or NUMERIC |
TimeZone | VARCHAR |
ZoneOffset | VARCHAR |
Hibernate recognizes these types and we only need to provide @Column
or @Basic
annotation in the field. Hibernate takes care of the choosing correct data types to store/update the values in these fields.
3. Demo
In this demo, we are creating an ArticleEntity
. It has 3 fields lastUpdateDate, lastUpdateTime and publishedTimestamp. Their corresponding JDBC types are DATE, TIME and TIMESTAMP.
Notice that we have not used the @Temporal
annotation as it is not required with new Java types.
@Entity
@Table(name = "TBL_ARTICLE")
public class ArticleEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@Column
private String title;
@Column
private String content;
@Column
private LocalDate lastUpdateDate;
@Column
private LocalTime lastUpdateTime;
@Column
private LocalDateTime publishedTimestamp;
//Getters and setters are hidden for brevity
}
Now let us first persist an instance of ArticleEntity
and check for the data types in CREATE query.
LocalDate date = LocalDate.of(1990, 1, 1);
LocalTime time = LocalTime.of(10, 10);
LocalDateTime timestamp = LocalDateTime.of(1990, 1, 1, 10, 10);
ArticleEntity article = new ArticleEntity();
article.setTitle("Title");
article.setContent("Content");
article.setLastUpdateDate(date);
article.setLastUpdateTime(time);
article.setPublishedTimestamp(timestamp);
session.persist(article);
The CREATE query generated for this operation is as follows. Notice the JDBC types are date, time and timestamp.
create table TBL_ARTICLE (
id bigint generated by default as identity,
content varchar(255),
title varchar(255),
lastUpdateDate date,
lastUpdateTime time,
publishedTimestamp timestamp(6),
primary key (id)
)
Now we will fetch this entity from the database and verify that we are able to get the same values that we inserted into the database.
ArticleEntity fetchedArticle = session.get(ArticleEntity.class, article.getId());
Assertions.assertEquals(fetchedArticle.getLastUpdateDate(), date);
Assertions.assertEquals(fetchedArticle.getLastUpdateTime(), time);
Assertions.assertEquals(fetchedArticle.getPublishedTimestamp(), timestamp);
The JUnit test passes successfully indicating that we are able to insert and fetch the Java date-time types into the database.
Happy Learning !!
Leave a Reply