0

I have a timestamp field in H2 database, but I need to get String instead of Date from my bean using Hibernate 4.3, so I'm trying to do like that in my bean:

import java.util.Date;

...

private Date msgDate;
@Column(name = "msgDate", columnDefinition="timestamp")
public String getMsgDate() {
    SimpleDateFormat df = new SimpleDateFormat("yyyy MM dd HH mm ss");
    return df.format(msgDate);
}

public void setMsgDate(Date msgDate) {
    this.msgDate = msgDate;
}

But I have next errors:

    ERROR: HHH000123: IllegalArgumentException in class: Messages, setter method of property: msgDate
июл 03, 2013 11:39:56 AM org.hibernate.property.BasicPropertyAccessor$BasicSetter set
ERROR: HHH000091: Expected type: java.util.Date, actual value: java.lang.String
июл 03, 2013 11:39:56 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [MessageList] in context with path [/messenger] threw exception
org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of com.epam.epamlab.messenger.beans.Messages.msgDate
    at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:119)
    at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:711)
    at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:371)
    at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:4519)
    at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:188)
    at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:144)
    at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1102)
    at org.hibernate.loader.Loader.processResultSet(Loader.java:959)
    at org.hibernate.loader.Loader.doQuery(Loader.java:906)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:340)
    at org.hibernate.loader.Loader.doList(Loader.java:2523)
    at org.hibernate.loader.Loader.doList(Loader.java:2509)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2339)
    at org.hibernate.loader.Loader.list(Loader.java:2334)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:491)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:369)
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:222)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1270)
    at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
    ...
Caused by: java.lang.IllegalArgumentException: argument type mismatch
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:65)
    ... 40 more

If I returns Date from getter, everything works nice. Why Hibernate waits Date type to be returned, even after using columnDefinition in annotations? How I should do this correctly?

goblin
  • 45
  • 3
  • 8

2 Answers2

2

Leave the getters/setters unaltered. Hibernate needs these methods to be consistent with the type of field in order to perform operations. Nothing stops you from defining your own special get method within the class.

private Date msgDate;
@Column(name = "msgDate", columnDefinition="timestamp")
public Date getMsgDate() {
   return this.msgDate;
}

public void setMsgDate(Date msgDate) {
    this.msgDate = msgDate;
}

public Date getMsgDateFormatted() {
    SimpleDateFormat df = new SimpleDateFormat("yyyy MM dd HH mm ss");
    return df.format(msgDate);
}
Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
  • It will be nice solution, but unfortunately not for my task. But thank's a lot for your answer, now I know what I should do. And [here](http://stackoverflow.com/questions/7081044/hibernate-how-to-set-sql-type-by-annotation) written that Hibernate can understand different getter and column type definitions, that's why I posted this question. – goblin Jul 03 '13 at 10:01
0

Why dont you write a utility method that takes Date as a input and returns you the formattedString. Hibernate internally makes use of these setter and getters and expects the datatype of entity attributes and database fields to be compliant.

Otherwise if you want this format to be exactly the same even in database, make this field as varchar in database and String in entity class.

So this is how your method will look like:

public String getFormattedMsgDate(Date msgDate) {
    SimpleDateFormat df = new SimpleDateFormat("yyyy MM dd HH mm ss");
    return df.format(msgDate);
}
ajay.patel
  • 1,957
  • 12
  • 15
  • After getting list of beans from database I'm sending it as a JSON with help of GSON lib, so getting String from bean is the most simple way. Store varchar instaed of timestamp in database is not correct ideologically I think. – goblin Jul 03 '13 at 09:42
  • i agree , and thats where i said its better that you have a utility method that does it for you. returns u a string. – ajay.patel Jul 03 '13 at 09:45