Hot questions for Using Joda-Time in jpa

Question:

I want to use JodaTime LocalDate with hibernate. I wrote this:

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "DATE_DEBUT", nullable = false)
@Type(type = "org.joda.time.contrib.hibernate.PersistentLocalDate")
private LocalDate dateDebut;

but it didn't work. I get this error :

Caused by: Exception [EclipseLink-7165] (Eclipse Persistence Services -   2.5.2.v20140319-9ad6abd):   org.eclipse.persistence.exceptions.ValidationException
Exception Description: The type [class org.joda.time.LocalDate] for the attribute [dateDebut] on the entity class [class ch.test.application.beans.mandat.Mandat] is not a valid type for a temporal mapping. The attribute must be defined as java.util.Date or java.util.Calendar.

Do you know why ?

Thanks


Answer:

You can use Jadira

All you have to is add this as dependency and then anotae like this:

@Column
  @Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
  private DateTime endTime;

For more info check their website.

There is another library that integrates Joda Time with Hibernate from Joda themselves. Here is the link. But personally I could not make it work for me.

Question:

Im making an app with JPA 2.1, eclipseLink, and a SQLite3 database.

I have a table of clients in which i save the clients birthdates in milliseconds.

In the entity client i use a converter for casting the birthdate value from DateTime (JodaTime) to Long:

@Converter
public class DateTimeConverter implements AttributeConverter<DateTime, Long> {

    @Override
    public Long convertToDatabaseColumn(DateTime arg0) {        
        return arg0 == null ? null : ((DateTime) arg0).getMillis();  
    }

    @Override
    public DateTime convertToEntityAttribute(Long arg0) {       
        return arg0 == null ? null : new DateTime(arg0);
    }
}

Im trying to get one of those clients by birthDate in JPQL, but i donĀ“t know how to do it. I tried several things, but none of them worked correctly. For example, i tried to do this:

EntityClient client = new EntityClient();
client.setBirthDate(new DateTime("1966-07-21"));

ArrayList<EntityClient> clientsByBirthdate = new ArrayList<>();

String query = "SELECT o FROM " + EntityClient.class.getCanonicalName() + " o " + 
                    "WHERE o.birthDate = " + client.getBirthDate().getMillis();

for(Object obj : entityManager.createQuery(query).getResultList())
    clientsByBirthdate.add(EntityClient.class.cast(obj));

But instead of retriving the correct record it retrives all the records with the birthdate set to null.

What im doing wrong?


Answer:

Never use String concatenation to pass parameters to a query. Use parameters:

String query = "SELECT o FROM EntityClient o " + 
                "WHERE o.birthDate = :birthDate";
List<EntityClient> list = 
    entityManager.createQuery(query, EntityClient.class)
                 .setParameter("birthDate", new DateTime("1966-07-21"))
                 .getResultList()

Question:

I'm starting a new spring mvc project. I'm using JPA for my entities mapping. I had an entity name Account with a dateTime field annotated as followed:

@Entity
public class Account implements Serializable{
    @Id
    @GeneratedValue
    private Long id;
    @Temporal(TemporalType.TIMESTAMP)
    private Date openinTime;
    ..........
}

and an entity Client with a Date field as followed

@Entity
public class Client {
    @Id
    @GeneratedValue
    private Long id;
    private String firstName;
    private String lastName;
    @Temporal(TemporalType.DATE)
    private Date birthDate;

}

in my Spring-mvc controller, i find an account by id and return it as followed

@RequestMapping(value = "/find", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<?> findAccountById(@RequestParam("accountId") Long accountId) {
    Account accountFound = accountService.findById(accountId);
    ResponseEntity<Account> responseEntity = new ResponseEntity<Account>(accountFound, HttpStatus.OK);
    return responseEntity;
}

but, when i saved an account object with date like "2016-12-07 12:00:00", and then, try to retrieve it, the date i'm getting on the client side is "1481108400000"

So i decide to use jodatime instead of java.util.Date (hoping that it will solve my problem)

I have configure in my spring-mvc xml dispatcher file the dateFormatter. this is my xml file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                   http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

<mvc:default-servlet-handler />

<!-- Login Interceptor -->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/protected/**" />
        <bean class="softbank.ui.interceptor.LoginInterceptor" />
    </mvc:interceptor>
    <!-- workaround to fix IE8 problem -->
    <bean id="webContentInterceptor"
        class="org.springframework.web.servlet.mvc.WebContentInterceptor">
        <property name="cacheSeconds" value="0" />
        <property name="useExpiresHeader" value="true" />
        <property name="useCacheControlHeader" value="true" />
        <property name="useCacheControlNoStore" value="true" />
    </bean>
</mvc:interceptors>

<!-- i18n -->
<bean id="messageSource"
    class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basename" value="WEB-INF/i18n" />
    <property name="defaultEncoding" value="UTF-8" />
    <property name="useCodeAsDefaultMessage" value="true" />
</bean>
<bean id="localeResolver"
    class="org.springframework.web.servlet.i18n.FixedLocaleResolver">
    <property name="defaultLocale" value="en" />
</bean>

<!-- View Handler -->
<bean
    class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="favorPathExtension" value="true" />
    <property name="mediaTypes">
        <map>
            <entry key="xml" value="text/xml" />
            <entry key="json" value="application/json" />
            <entry key="html" value="text/html" />
            <entry key="less" value="text/html" />
        </map>
    </property>
    <property name="viewResolvers">
        <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/" />
            <property name="suffix" value=".jsp" />
        </bean>
    </property>
</bean>

<bean id="objectMapper"
    class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
    p:indentOutput="true" p:simpleDateFormat="yyyy-MM-dd HH:mm:ss">
</bean>

<bean
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
    p:targetObject-ref="objectMapper" p:targetMethod="registerModule">
    <property name="arguments">
        <list>
            <bean class="com.fasterxml.jackson.datatype.joda.JodaModule" />
        </list>
    </property>
</bean>

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
        <bean
            class="org.springframework.http.converter.ResourceHttpMessageConverter" />
        <bean
            class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper" ref="objectMapper" />
        </bean>
        <bean
            class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter" />
    </mvc:message-converters>
</mvc:annotation-driven>

but i'm still getting and error : The prefix "p" for attribute "p:indentOutput" associated with an element type "bean" is not bound


Answer:

You must declare the p XML namespace as xmlns:p="http://www.springframework.org/schema/p" in your <beans> element:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    ... <other namespaces> ...
>

After that, the JodaModule for Jackson should automatically format your JodaTime types.