0

-----Situation-----

I have a REST API built with Java. I used technologies like Jersey, Hibernate. The REST API is being called from our mobile app. In most cases, the REST API passes java beans when we retrieve data and mobile app also passes java beans when we send data.

We have lot of Java Beans and below is an example of a simple one with its Hibernate mapping.

Units.java

import java.util.Date;

/**
 * Units generated by hbm2java
 */
public class Units  implements java.io.Serializable {

     private Integer idunits;
     private Patient patient;
     private UnitType unitType;
     private String unitMeasurement;
     private Date dateCreated;
     private Date lastUpdated;

    public Units() {
    }


    public Units(Patient patient, UnitType unitType, String unitMeasurement, Date lastUpdated) {
        this.patient = patient;
        this.unitType = unitType;
        this.unitMeasurement = unitMeasurement;
        this.lastUpdated = lastUpdated;
    }
    public Units(Patient patient, UnitType unitType, String unitMeasurement, Date dateCreated, Date lastUpdated) {
       this.patient = patient;
       this.unitType = unitType;
       this.unitMeasurement = unitMeasurement;
       this.dateCreated = dateCreated;
       this.lastUpdated = lastUpdated;
    }

    public Integer getIdunits() {
        return this.idunits;
    }

    public void setIdunits(Integer idunits) {
        this.idunits = idunits;
    }
    public Patient getPatient() {
        return this.patient;
    }

    public void setPatient(Patient patient) {
        this.patient = patient;
    }
    public UnitType getUnitType() {
        return this.unitType;
    }

    public void setUnitType(UnitType unitType) {
        this.unitType = unitType;
    }
    public String getUnitMeasurement() {
        return this.unitMeasurement;
    }

    public void setUnitMeasurement(String unitMeasurement) {
        this.unitMeasurement = unitMeasurement;
    }
    public Date getDateCreated() {
        return this.dateCreated;
    }

    public void setDateCreated(Date dateCreated) {
        this.dateCreated = dateCreated;
    }
    public Date getLastUpdated() {
        return this.lastUpdated;
    }

    public void setLastUpdated(Date lastUpdated) {
        this.lastUpdated = lastUpdated;
    }

}

Units.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Sep 23, 2016 3:21:00 PM by Hibernate Tools 4.3.1 -->
<hibernate-mapping>
    <class name="beans.Units" table="units" catalog="myglukose" optimistic-lock="version">
        <id name="idunits" type="java.lang.Integer">
            <column name="idunits" />
            <generator class="identity" />
        </id>
        <many-to-one name="patient" class="beans.Patient" fetch="select">
            <column name="patient_idpatient" not-null="true" />
        </many-to-one>
        <many-to-one name="unitType" class="beans.UnitType" fetch="select">
            <column name="unit_type_idunit_type" not-null="true" />
        </many-to-one>
        <property name="unitMeasurement" type="string">
            <column name="unit_measurement" length="45" not-null="true" />
        </property>
        <property name="dateCreated" type="timestamp">
            <column name="date_created" length="19" />
        </property>
        <property name="lastUpdated" type="timestamp">
            <column name="last_updated" length="19" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

Here, the dateCreated and lastUpdated are actually timestamp in our MySQL database.

However whenever we send the data from mobile app to REST API , we noticed that "time" in timestamp values (ex: dateCreated, lastUpdated) are actually changed and saved in database. We are in GMT +5.30, so if we send time as 12.28PM to the REST API, what get saved in DB is 17:58. Either we saved in local database or in Amazon RDS, the same happens. When retrieving, we get what was saved, 17:58 which is wrong.

Our application will be used by people in different timezones, so we can't stick to one timezone as well.

------What we planned------

This situation is pretty annoying and we failed to find a solution. The best solution we can think of is sending the time from phone to REST API as a String, and in server convert it back to a Date object.

So, we propose the following solution. Currently our java beans represents the fields of the exact table and nothing else. Now we are planning about adding more variables into it, to hold this String time we are sending. As for an example, check below, it is the same bean I posted above with applicable changes.

package beans;
// Generated Sep 23, 2016 3:21:00 PM by Hibernate Tools 4.3.1


import java.util.Date;

/**
 * Units generated by hbm2java
 */
public class Units  implements java.io.Serializable {

     private Integer idunits;
     private Patient patient;
     private UnitType unitType;
     private String unitMeasurement;
     private Date dateCreated;
     private Date lastUpdated;
     private String lastUpdatedStr;
     private String dateCreatedStr;

    public Units() {
    }


    public Units(Patient patient, UnitType unitType, String unitMeasurement, Date lastUpdated) {
        this.patient = patient;
        this.unitType = unitType;
        this.unitMeasurement = unitMeasurement;
        this.lastUpdated = lastUpdated;
    }
    public Units(Patient patient, UnitType unitType, String unitMeasurement, Date dateCreated, Date lastUpdated) {
       this.patient = patient;
       this.unitType = unitType;
       this.unitMeasurement = unitMeasurement;
       this.dateCreated = dateCreated;
       this.lastUpdated = lastUpdated;
    }

    public Integer getIdunits() {
        return this.idunits;
    }

    public void setIdunits(Integer idunits) {
        this.idunits = idunits;
    }
    public Patient getPatient() {
        return this.patient;
    }

    public void setPatient(Patient patient) {
        this.patient = patient;
    }
    public UnitType getUnitType() {
        return this.unitType;
    }

    public void setUnitType(UnitType unitType) {
        this.unitType = unitType;
    }
    public String getUnitMeasurement() {
        return this.unitMeasurement;
    }

    public void setUnitMeasurement(String unitMeasurement) {
        this.unitMeasurement = unitMeasurement;
    }
    public Date getDateCreated() {
        return this.dateCreated;
    }

    public void setDateCreated(Date dateCreated) {
        this.dateCreated = dateCreated;
    }
    public Date getLastUpdated() {
        return this.lastUpdated;
    }

    public void setLastUpdated(Date lastUpdated) {
        this.lastUpdated = lastUpdated;
    }

    /**
     * @return the lastUpdatedStr
     */
    public String getLastUpdatedStr() {
        return lastUpdatedStr;
    }

    /**
     * @param lastUpdatedStr the lastUpdatedStr to set
     */
    public void setLastUpdatedStr(String lastUpdatedStr) {
        this.lastUpdatedStr = lastUpdatedStr;
    }

    /**
     * @return the dateCreatedStr
     */
    public String getDateCreatedStr() {
        return dateCreatedStr;
    }

    /**
     * @param dateCreatedStr the dateCreatedStr to set
     */
    public void setDateCreatedStr(String dateCreatedStr) {
        this.dateCreatedStr = dateCreatedStr;
    }
}

As you can see, we have added new variables lastUpdatedStr and dateCreatedStr. Anyway, please NOTE: WE DID NOT MAP THESE TO THE Units.bhm.xml FILE BECAUSE THESE HAS NOTHING TO DO WITH Hibernate.

--------Question--------

  1. Is what we are planning to do a good programming practice?
  2. We didn't map the variables into hibernate because they are not database columns and hibernate has nothing to do with it. But, will hibernate somehow mess up with these like trying to set values somehow? We ran a small test. Seems not.
  3. We experienced this timestamp change only when sending Date objects (with time, of course) from android to REST and saving to DB. When retrieving them back to mobile, we received what was saved (ex: we sent 12:28PM to REST but it was saved as 17:58. When retrieving we received 17:58). However we did not check with users in different countries so we don't know whether it will be that way, always. We are not planning to retrieve these as String objects from database to mobile via REST, instead get Date objects and work with it. One reason for this is we are using Retrofit for making REST calls and we have a custom GSON Date Serializer, so we have to send Date objects anyway. So, can this will be a problem in one day and should we retrieve Date objects converted to String as well?
PeakGen
  • 21,894
  • 86
  • 261
  • 463

1 Answers1

-1

we noticed that "time" in timestamp values (ex: dateCreated, lastUpdated) are actually changed and saved in database. We are in GMT +5.30, so if we send time as 12.28PM to the REST API, what get saved in DB is 17:28

Which value you are getting from database while retrieving same record? either 12.28PM or 17.28PM?

If retrieved value is 12.28 then automatic conversation made by database like PostgreSQL. And I think this would be fine for you.

Nilesh Jadav
  • 890
  • 9
  • 8