-----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--------
- Is what we are planning to do a good programming practice?
- 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.
- We experienced this
timestamp
change only when sendingDate
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 asString
objects from database to mobile via REST, instead getDate
objects and work with it. One reason for this is we are usingRetrofit
for makingREST
calls and we have a customGSON
Date Serializer, so we have to sendDate
objects anyway. So, can this will be a problem in one day and should we retrieveDate
objects converted toString
as well?