JPA 2.x and the LocalDate API

Before Java 8 was released we all worked with the java.util.Date class and their methods.
And it was just annoying (at least for me). Everything you wanted to do was a bit complex and mostly it didn´t work as it was supposed to be.

But Java 8 brought the remedy for this. The glorious LocalDate API.
It just makes everything so much more simple and so much easier to handle.

But there is one thing I am still missing: The LocalDate API when I write Entities that are handled in a JPA Context. So made Oracle something bad and we still must use the util.Date Type…. or may be a salvation for this annoying thing in JPA?

Yes there is one! A LocalDateConverter – let´s get it implemented!

Implement the Entity

You´re having a JPA Project, with a valid Persistence.xml and a working Database Connection.
So let´s setup a simple User Entity

package com.javadevcorner.entity;

import java.time.LocalDate;
import javax.persistence.Entity;
import javax.persistence.Id;

/**
 *
 * @author javadevcorner.com
 */
@Entity
public class User {

    @Id
    private long id; 
    private String name;
    private LocalDate birthday;
    
    //default constructor - setter and getter
}

Please pay attention and watch the birthday attribute which is LocalDate not util.Date

Implement the LocalDateConverter

Now it´s time to develop the magic things. Create a class called LocalDateConverter which implements the AttributeConverter<x,y> Interface as follows

package com.javadevcorner.typeConverter;


import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

/**
 *
 * @author javadevcorner.com
 */
@Converter(autoApply = true)
public class LocalDateConverter implements AttributeConverter<localdate, date=""> {

    //From Entity to Database
    @Override
    public Date convertToDatabaseColumn(LocalDate localDate) {
        if (localDate != null) {
            return Date
                 .from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
        } else {
            return null;
        }
    }
    
    //From Database to Entity
    @Override
    public LocalDate convertToEntityAttribute(Date date) {
        if (date != null) {
            return LocalDate.from(date.toInstant());
        } else {
            return null;
        }
    }

}

We are forced to override the methods of AttributeConverter<x,y>.
Please don´t forget to annotate the LocalDateConverter with @Converter(autoApply = true). Only using this annotation will have the effect we want to. It will force the Converter to automatically be activated, when you want to receive data from the database or want to store some new values to your database. 

If it is not possible that your attribute can be null (such as by a database constraint) you can omit that null check. But it is good to have one. You never know, trust me 😉

So thanks for reading and have fun using the LocalDateConverter.

 

Feel free to share

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.