I have an Hibernate class and for a time column in MySqlDb I'm using in Java
#Type(type="org.joda.time.contrib.hibernate.PersistentLocalTimeAsTime")
#Column(name = "hour", length = 8)
public LocalTime getHour() {
return this.hour;
}
So my problem is if I have in DB 07:20:33
when I get the value I have 06:20:33
Related
I am trying to find a Java Time Type that can be persisted to a column of type TIMESTAMP WITH TIME ZONE in the Oracle DB. The Java type needs to have the Time Zone as part of it. Because of the way the application was written, the Java Calendar type was used (also, the Java Calendar type has Time Zone that is part of it)
TRIAL ONE:
I did try to use the Calendar directly (with no serializer) with this code:
dateStr was in a pattern of: "MM-dd-yyyy hh:mm:ss a"
ZoneLoc was for the timezone: ex: America/Chicago, US/Eastern, etc.
public Calendar convDateStrWithZoneTOCalendar(String dateStr,
String ZoneLoc) throws Exception {
String string = dateStr;
String pattern = this.getPattern();
Date date = new SimpleDateFormat(pattern).parse(string);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
TimeZone tz = TimeZone.getTimeZone(ZoneLoc);
calendar.setTimeZone( tz );
return calendar;
}
when using this, the correct Zone Location was not set. For example, I would try to set ZoneLoc to US/Hawaii and when data was saved to the DB, it would be something like
23-SEP-19 10.03.11.000000 AM -05:00 And (-05:00) does not represent US/Hawaii
TRIAL TWO
It is for this reason why the attribute-conversion route was tried. In this case, there is an attempt to convert Calendar to ZoneDateTime.
I had seen this in another message noting:
Add #Convert(converter=OracleZonedDateTimeSeriliazer.class) on top of
your createdOn attribute on ur Entity class.
But, as mentioned above, Calendar is being used as part of the entity and not ZonedDateTime
the way the entity class is defined now. Before (when using the ( convDateStrWithZoneTOCalendar above), the "#Convert" items were not present
#Entity
#Table(name = "LAWNCORRJOB", schema = "ORAAPPS", uniqueConstraints = #UniqueConstraint(columnNames = {
"TENANTID", "GENERATEDJOBNO" }))
public class Lawncorrjob implements java.io.Serializable {
private static final long serialVersionUID = -8207025830028821136L;
....
#Convert( converter = OracleCalendarZoneDateTimeSerializer.class, disableConversion = false )
private Calendar schedfirstdayts;
#Convert( converter = OracleCalendarZoneDateTimeSerializer.class, disableConversion = false )
private Calendar schedlastdayts;
...
}
the converter being used: converts Calendar to ZonedDateTime (under Oracle)
#Converter(autoApply = true)
public class OracleCalendarZoneDateTimeSerializer implements
AttributeConverter<Calendar, ZonedDateTime> {
#Override
public ZonedDateTime convertToDatabaseColumn(Calendar attribute) {
if (attribute == null)
return null;
// get the timezone
TimeZone tz = attribute.getTimeZone();
// use the timezone to specify the area location
// ex: For example, TimeZone.getTimeZone("GMT-8").getID() returns
// "GMT-08:00".
ZonedDateTime xzdt = ZonedDateTime.of(attribute.get(Calendar.YEAR),
attribute.get(Calendar.MONTH),
attribute.get(Calendar.DAY_OF_MONTH) + 1,
attribute.get(Calendar.HOUR_OF_DAY),
attribute.get(Calendar.MINUTE), attribute.get(Calendar.SECOND),
attribute.get(Calendar.MILLISECOND), ZoneId.of(tz.getID()));
return xzdt;
}
#Override
public Calendar convertToEntityAttribute(ZonedDateTime dbData) {
GregorianCalendar newcal = DateTimeUtils.toGregorianCalendar(dbData);
return newcal;
}
}
But, when executing this code, I get an error:
Error Message: Could not commit JPA transaction; nested exception is
javax.persistence.RollbackException: Error while committing the
transaction CAUSE : javax.persistence.RollbackException: Error while
committing the transaction",
So, is there any way I can fix either option to get this all working?
Any help, hints or advice is appreciated.
TIA
Given this Entity I need to post the new Object of type Contracts. I
http://www.springframework.org/tags/form tag form/sf. I also got jquery datapicker. The problem I have got is datapicker returns a String not Date object. How can it be parsed? The only solution I think will work is to get date from datepicker as #RequestParam in the #Controller class and parse it as a java.util.Date object.
#Entity
#Table(name = "contract")
public class Contracts {
#Id
#Column(name = "contract_id")
private int contractId;
#Column(name = "date_added")
private Date creationDate;
#Column(name = "date_start")
private Date startDate;
#Column(name = "date_end")
private Date finishDate;
#NotNull
#Column(name = "payment_amount")
private Integer paymentAmount;
#Column(name = "payment_type")
#Enumerated(EnumType.STRING)
private PaymentType paymentType;
private boolean valid;
#ManyToOne
#JoinColumn(name = "system_id")
private Systems system;
And this is 'POST' part of my Controller class.
#RequestMapping(value = "/createcontract", method = RequestMethod.POST)
public String createContract(#ModelAttribute("contract") #Valid final Contracts contract, BindingResult results,
#RequestParam("system-id") int systemId) {
if(results.hasErrors())
return "newcontract";
return "redirect:contracts";
Another question (because I tagged postgresql) is whether is 'all-right' to store java.util.Data object in postgresql as just date or maybe I should store it as 'timestamp with time zone'?
jQuery UI DatePicker gives Date object
The plugin allows you to obtain a Date object using getDate method.
Here is a Plunker with a working example.
$(function() {
$('#datePicker').datepicker();
$('#datePicker').on('change', () => {
let date = $('#datePicker').datepicker('getDate');
alert(`Date ${date} is ${date instanceof Date ? 'a Date object' : 'not a Date object'}`);
});
});
Date type - JPA to PostgreSQL mapping
Use timestamp with time zone in PostgreSQL
Usually is best to keep your dates as UTC in your database. This will give the most flexibility as you can represent the date in whichever zone you desire. This translates into using the timestamp with time zone as a type which will store as UTC. This means that your date time, before being stored, is added the zone offset in order to obtain the UTC.
Set the timezone to UTC of your JVM or your JPA provider
Is important that all your dates are expressed as UTC and not in a specific time zone. And when these are sent via the wire to your database the session needs to have the UTC time zone.
This means that the timezone needs to be UTC on JVM or JPA provider (eg: Hibernate).
As explained in this blog you can set UTC by:
JVM: java -Duser.timezone=UTC -jar blabla.jar
Or by
JVM: TimeZone.setDefault(TimeZone.getTimeZone("Etc/UTC"));
Or by
Hibernate: (application.properties) spring.jpa.properties.hibernate.jdbc.time_zone = UTC
Check which version works for you.
Persisting Date field
Therefore your field can be expressed as:
#Column(name = "date_added", columnDefinition = "TIMESTAMP WITH TIMEZONE")
#Temporal(TemporalType.TIMESTAMP)
private Date creationDate;
And you need to ensure that the Date object represents a date time in UTC.
Useful mappings
You can store your Date object in PostgreSQL as:
timestamp with or without timezone
time with or without timezone
date
Using the JPA annotation #Temporal applied on your Date field you can specify how the object is being mapped:
#Temporal(TIMESTAMP) to timestamp
#Temporal(DATE) to date
#Temporal(TIME) to time
Also specifying that your column is timestamp with timezone can be stated using annotation #Column(columnDefinition = "TIMESTAMP WITH TIMEZONE").
import java.sql.Timestamp;
oR
import java.sql.Date;
add this import ur pojo .
I have an Oracle database which contains a field W_PLANNED_DATE: 19/03/2013 10:55:00 (Date)
In Java I put this value into a variable:
Date dteBeginOrWaitingItem = orWaitinglist.getWPlannedDate();
value: 2013-03-19
Now, what happend to my time? I need this to fill the schedulecomponent of primefaces.
How can i get a full date and time value
eventResourceAvailPerDay.addEvent(new DefaultScheduleEvent(reason, dteBeginOrWaitingItem, dteEndOrWaitingItem, "waitingitem"));
This method puts the event at 12:00 PM as there is no other time or the time is just 00:00:00
I know how to use the Calendar class but it just lets me set the date, the time seems to be empty but in database view I have a date time value.
Mybean
import java.util.Date;
#ManagedBean(name="scheduleController")
#SessionScoped
public class ScheduleController implements Serializable {
private Date dteBeginOrWaitingItem, dteEndOrWaitingItem;
//methods
try
{
//eventWaitinglist.clear();
OrWaitinglistDao orWaitinglistDao = new OrWaitinglistDaoImpl();
waitingEvents = orWaitinglistDao.getOrWaitinglistKeysByResource(rKey);
int i = 0;
Iterator<OrWaitinglist> it2 = waitingEvents.iterator();
while (it2.hasNext())
{
orWaitinglist = it2.next();
dteBeginOrWaitingItem = (Date) orWaitinglist.getWPlannedDate();
dteEndOrWaitingItem = orWaitinglist.getWPlannedDate();
//dteEndOrWaitingItem = orWaitinglist.getWPlannedDate();
reason = orWaitinglist.getWDescription();
eventResourceAvailPerDay.addEvent(new DefaultScheduleEvent(reason, dteBeginOrWaitingItem, dteEndOrWaitingItem, "waitingitem"));
i += 1;
System.out.println("EventWaiting: " + i + " " + dteBeginOrWaitingItem + " " + dteEndOrWaitingItem + " " + reason);
}
}
catch(java.util.EmptyStackException Ex)
{
System.out.println(Ex.getMessage());
}
WORKING UPDATE:
Bean:
try
{
//eventWaitinglist.clear();
OrWaitinglistDao orWaitinglistDao = new OrWaitinglistDaoImpl();
waitingEvents = orWaitinglistDao.getOrWaitinglistKeysByResource(rKey);
int i = 0;
Iterator<OrWaitinglist> it2 = waitingEvents.iterator();
while (it2.hasNext())
{
orWaitinglist = it2.next();
Long wPlannedDate = orWaitinglist.getWPlannedDate().getTime();
if (wPlannedDate != 0) {
Date wPlannedDateConverted = new Date(wPlannedDate);
dteBeginOrWaitingItem = convertDate(0, 0, wPlannedDateConverted);
dteEndOrWaitingItem = convertDate(orWaitinglist.getWDuration().intValue(), orWaitinglist.getWAdditionalTime().intValue(), wPlannedDateConverted);
}
reason = orWaitinglist.getWDescription();
DefaultScheduleEvent newResourceEvent = new DefaultScheduleEvent(reason, dteBeginOrWaitingItem, dteEndOrWaitingItem, orWaitinglist);
newResourceEvent.setStyleClass("waitingitem");
eventResourceAvailPerDay.addEvent(newResourceEvent);
}
}
catch(java.util.EmptyStackException Ex)
{
System.out.println(Ex.getMessage());
}
public static Date convertDate(Integer wDuration, Integer wAdditionalTime, Date availDate)
{
Calendar cal = Calendar.getInstance();
Integer wAdditionalTimeHours, wAdditionalTimeMinutes;
Integer wDurationHours, wDurationMinutes;
if(wAdditionalTime != 0 || wDuration != 0) {
if (wAdditionalTime !=0) {
wAdditionalTimeHours = (int) Math.floor (wAdditionalTime / 60);
wAdditionalTimeMinutes = wAdditionalTime - (wAdditionalTimeHours * 60);
cal.setTime(availDate);
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE), cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
cal.add(Calendar.MINUTE, wAdditionalTimeMinutes);
cal.add(Calendar.HOUR_OF_DAY, wAdditionalTimeHours);
}
if (wDuration != 0) {
wDurationHours = (int) Math.floor (wAdditionalTime / 60);
wDurationMinutes = wAdditionalTime - (wDurationHours * 60);
cal.setTime(availDate);
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE), cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
cal.add(Calendar.MINUTE, wDurationMinutes);
cal.add(Calendar.HOUR_OF_DAY, wDurationHours);
}
} else {
cal.setTime(availDate);
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE), cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
}
return cal.getTime();
}
Model update:
<property name="WPlannedDate" type="timestamp">
<column length="7" name="W_PLANNED_DATE">
<comment>Planned date</comment>
</column>
</property>
java.sql.Date will not return time component, you should use java.util.Date while creating your preparedstatement or any other way your are querying the db.
EDIT:
Using java.util.Date with sql query can be tricky as query will expect java.sql.Date. It works for me in Spring. If you dont want to use this then you can use java.sql.Timestamp also.
See below documentation:
8.3.12 DATE, TIME, and TIMESTAMP
There are three JDBC types relating to time:
The JDBC DATE type represents a date consisting of day, month, and
year. The corresponding SQL DATE type is defined in SQL-92, but it is
implemented by only a subset of the major databases. Some databases
offer alternative SQL types that support similar semantics. The JDBC
TIME type represents a time consisting of hours, minutes, and seconds.
The corresponding SQL TIME type is defined in SQL-92, but it is
implemented by only a subset of the major databases. As with DATE,
some databases offer alternative SQL types that support similar
semantics. The JDBC TIMESTAMP type represents DATE plus TIME plus a
nanosecond field. The corresponding SQL TIMESTAMP type is defined in
SQL-92, but it is implemented by only a very small number of
databases. Because the standard Java class java.util.Date does not
match any of these three JDBC date/time types exactly (it includes
both DATE and TIME information but has no nanoseconds), JDBC defines
three subclasses of java.util.Date to correspond to the SQL types.
They are:
java.sql.Date for SQL DATE information. The hour, minute, second, and
millisecond fields of the java.util.Date base class should be set to
zero. If the number of milliseconds supplied to the java.sql.Date
constructor is negative, the driver will compute the date as the
number of milliseconds before January 1, 1970. Otherwise, the date is
computed as the specified number of milliseconds after January 1,
1970.
java.sql.Time for SQL TIME information. The year, month, and day
fields of the java.util.Date base class are set to 1970, January, and
1. This is the "zero" date in the Java epoch. java.sql.Timestamp for SQL TIMESTAMP information. This class extends java.util.Date by adding
a nanoseconds field.
EDIT: if you are using .xml for hibernate change type to timestamp instead of date.
<property name="yourdate" column="YOUR_DATE" type="timestamp" />
therefore you have time on your database and can use simpledateformat
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy-HH:mm");
dateFormat.format(orWaitinglist.getWPlannedDate());
Instead of java.sql.Date, java.sql.Timestamp and the matching methods should be used. The oracle type DATE is equivalent to the JDBC and SQL-standard type TIMESTAMP.
A driver is required by the JDBC spec to exclude the time part when one of the get/setDate methods are used.
I have an Oracle function which accepts amongst other things, a date as parameter, and returns a date. The function is like this:
FUNCTION my_func(par1 IN DATE, par2 IN NUMERIC) RETURN DATE AS
ret_val DATE;
BEGIN
....
END;
I need to call this function in my Java application, and am currently doing so with JPQL. The code is for a web application running on JBoss 5, and looks like this:
Query q = entityMng.createNativeQuery("SELECT MY_FUNC(?1,?2) FROM DUAL");
java.util.Date now = new Date();
long param2 = 110L;
q.setParameter(1, now);
q.setParameter(2, param2);
java.sql.Date retSql = null;
Object obj = q.getSingleResult();
if (obj != null) {
retSql = (java.sql.Date) obj;
}
After executing the code the retSql variable contains the correct date but has a time = 00.00.000. I obtain the same behaviour even when using java.util.Date as opposed to java.sql.Date, as the type for retSql.
While investigating this problem I cam across this SO post How to convert correctly an Oracle Date field into java.util.Date through JPA, but I don't understand how to use "addScalar" in my case.
Any help would be appreciated, thanks in advance.
Try returning a TIMESTAMP in your function, not a DATE. DATE is now only a date in Oracle, and TIMESTAMP is suppose to be used for date/time. There is a backward compatibility flag you can set in JDBC to control this.
What JPA provider are you using? EclipseLink should be handling this automatically.
What about using XMLAdapter;
public class DateAdapter extends XmlAdapter {
// the desired format
private String pattern = "yyyy-MM-dd HH:mm:ss";
/*few more formats http://www.xyzws.com/javafaq/how-to-use-simpledateformat-class-formating-parsing-date-and-time/142 */
public String marshal(Date date) throws Exception {
return new SimpleDateFormat(pattern).format(date);
}
public Date unmarshal(String dateString) throws Exception {
return new SimpleDateFormat(pattern).parse(dateString);
}
And then adding it to your Entity; for example
private java.util.Date originDate;
#XmlJavaTypeAdapter(DateAdapter.class)
#Column(name = "ORIGIN_DATE", nullable = true)
#XmlElement(namespace = "my-namespace")
public Date getOriginDate() {
return this.originDate;
}
Here is a tutorial that I used to learned about this;
http://weblogs.java.net/blog/kohsuke/archive/2005/04/xmladapter_in_j.html
I have problems to get the full DATE info from my Oracle DB (dd/mm/yyyy hh/mm/ss).
In the db level, in the column that I want to receive I set test values:
update my_table
set my_date_column=(to_date('2011-06-15 15:43:12', 'yyyy-mm-dd hh24:mi:ss'));
but in my JPA entity I have:
#Column(name = "MY_DATE_COLUMN")
#Temporal(TemporalType.DATE)
private Date dateDetailed;
public Date getDateDetailed() {
if (this.dateDetailed!= null) {
return this.dateDetailed;
}
return null;
}
public void setDateDetailed(Date dateDetailed) {
if (dateDetailed!= null) {
this.dateDetailed= dateDetailed;
} else {
this.dateDetailed= null;
}
}
Each time I acccess my object, It is giving me date without hours, min and seconds.
I tried to use TemporalType.TIMESTAMP, but in that case I would need to also change column type in db (which I want to avoid).
Any suggestions?
Its the TemporalType.DATE
You will need TIME or TIMESTAMP. DATE is only the date without time. TIMESTAMP is represented as a number.
By using the TIMESTAMP temporal type, you will get the date and the time part of the java date datatype but Oracle will make a column with the TIMESTAMP datatype. To overcome this issue if you want a DATE datatype, you can use the columnDefinition parameter of the column annotation such as:
#Column(name = "MY_DATE_COLUMN", columnDefinition = "DATE")
#Temporal(TemporalType.TIMESTAMP)
private Date dateDetailed;