Store Date and Time in Oracle Date Column - java

I am migrating a DB2 table to an Oracle database using JPA and JEE. Because of this, I'm having problems with the "Date" and "Time" type columns. More specifically, in Oracle there is no data type "Time", so I'm trying to store from DB2 the concatenation of 2 columns (one of type Date and another of type Time) inside a column of type "Date" of the Oracle database. This way, I show you how I defined the column in the Oracle database and the mapping I defined:
, DATA_HORA_CREACIO DATE DEFAULT
TO_DATE('0001-01-01-00.00.00','YYYY-MM-DD-HH24.MI.SS')
NOT NULL
private Date dataHoraCreacio;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "DATA_HORA_CREACIO", nullable = false)
public Date getDataHoraCreacio() {
return this.dataHoraCreacio;
}
public void setDataHoraCreacio(Date dataHoraCreacio) {
this.dataHoraCreacio = dataHoraCreacio;
}
SimpleDateFormat sdfDateHour = new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss");
String data = sdfDate.format(comandaAvariaDb2.getId().getDataCreacio());
String hora = sdfHour.format(comandaAvariaDb2.getId().getHoraCreacio());
comandaAvariaOraId.setDataHoraCreacio(sdfDateHour.parse(data + "-" + hora));
Even so, although the work variable that covered the information is correctly informed, the part referring to the time is stored and not inserted in the database:
Variable working data: Thu Feb 02 18:42:53 CET 2006
DataBase inserted Value: 2006-02-02
I've been trying things out for several hours without making it work. Even so, if I have managed to work with a column of type "Timestamp" but I do not think the best solution because the milliseconds occupy an unnecessary space.
Any ideas?
Thanks in advance.

If you use an Oracle DATE value for DATA_HORA_CREACIO, you should be able to directly insert timestamps from DB2. It's just that selecting a DATE column without any hints for output will give you only the date-part in display:
CREATE TABLE STACK2
(DATA_HORA_CREACIO DATE
DEFAULT TO_DATE('0001-01-01-00.00.00',
'YYYY-MM-DD-HH24.MI.SS') NOT NULL);
INSERT INTO STACK2 VALUES
(TO_DATE('2017-05-30-16.47.32','YYYY-MM-DD-HH24.MI.SS'));
SELECT DATA_HORA_CREACIO,
TO_CHAR(DATA_HORA_CREACIO, 'YYYY-MM-DD'),
TO_CHAR(DATA_HORA_CREACIO, 'HH24:MI:SS') FROM STACK2;
Result is:
See this extract from Oracle DATE definition:
DATE Datatype
The DATE datatype stores date and time information.
Although date and time information can be represented in both
character and number datatypes, the DATE datatype has special
associated properties. For each DATE value, Oracle stores the
following information: century, year, month, date, hour, minute, and
second.

Related

JDBC and oracle database timezone handling

I have created sample table in oracle DB as below
"CREATED_ON" TIMESTAMP (6),
"CREATED_ON_TIMEZONE" TIMESTAMP (6) WITH TIME ZONE,
"TIMEZONE_GMT" TIMESTAMP (6) WITH TIME ZONE
and inserted values from java as below
preparedStatement.setTimestamp(1, new Timestamp(new Date().getTime()));
preparedStatement.setTimestamp(2, new Timestamp(new Date().getTime()));
preparedStatement.setTimestamp(3, new Timestamp(new Date().getTime()) ,Calendar.getInstance(TimeZone.getTimeZone("UTC")));
JVM timezone in ASIA/CALCUTTA. I have used SQL developer to query data.
I just wanted to clear my understanding
The first column stored value as per local JVM without timezone since dataType is only timestamp i.e 29-NOV-17 07.04.28.014000000 PM. so for column with timstamp datatype DB stores value as of local JVM which is passed by JDBC driver and there is no conversion happening either JDBC side or DB side ?
Second column store value with TIMEZONE i.e 29-NOV-17 07.04.28.014000000 PM
ASIA/CALCUTTA. So does it mean DB stores value for column with timezone information provided by JDBC driver and there is no convrsion at DB side?
I want to store value in GMT so I set third parameter as GMT , it store value in GMT but timezone was still showing as of local JVM . i.e 29-NOV-17 01.34.28.014000000 PM ASIA/CALCUTTA
I was refering below article but my observations looks totally diffrent.
http://brian.pontarelli.com/2011/08/16/database-handling-for-timezones/
Problem is Java Timestamp does not contain any time zone information.
So you insert a TIMESTAMP value into a column of TIMESTAMP WITH TIME ZONE. In such case Oracle makes an implicit cast with FROM_TZ:
FROM_TZ(<your value>, SESSIONTIMEZONE)
Command preparedStatement.setTimestamp(3, new Timestamp(new Date().getTime()) ,Calendar.getInstance(TimeZone.getTimeZone("UTC"))); would be correct only after an ALTER SESSION SET TIME_ZONE = 'UTC';

Wrong date selection in SQL

I'm working with Hibernate 4.3.8.Final, Primefaces 6.0 and MySQL Database 5.7.13.
I have a table in the database with this structure:
CREATE TABLE `rents` (
`rent_code` INT NOT NULL AUTO_INCREMENT,
`rent_daystart` datetime default NULL,
`rent_dayend` datetime default NULL,
PRIMARY KEY (`rent_code`)
) ENGINE = innodb CHARACTER SET utf8 COLLATE utf8_unicode_ci;
And the following data extracted with Squirrel with the following SQL:
select * from rents
rent_code | rent_daystart | rent_dayend
1 | 2016-11-30 16:03:00.0 | 2016-12-01 16:03:00.0
In my Java bean I have the following function:
public List<Object> getRents(java.util.Date iniDate, java.util.Date endDate){
String SQL="select rent_code from rents where rent_daystart < :inidate and rent_dayend > :enddate";
List<Object> allRecords = null;
Session sesion=HibernateUtil.getSessionFactory().openSession();
try {
sesion.beginTransaction();
Query query = sesion.createSQLQuery(SQL).setDate("inidate", iniDate).setDate("enddate", endDate);
allRecords = query.list();
sesion.getTransaction().commit();
sesion.close();
}
catch (HibernateException he) {
//exception control code
};
return allRecords;
}
I execute the web APP debugging and the dates that the function receives are:
**inidate** = 'Wed Nov 30 17:54:00 CET 2016'
**enddate** = 'Wed Nov 30 18:54:00 CET 2016'
And it returns NO RECORD AT ALL.
If I execute the same SQL in squirrel that way:
select rent_code from rents where rent_daystart < '2016-11-30 17:54:00' and rent_dayend > '2016-11-30 18:54:00'
It returns one record.
I suspect that this is a data type problem or something like that, but after researching in the web it is not clear to me.
May someone help me?
Thanks in advance!
The java.util.Date class doesn't handle time zones. Unless you are using the same time zone in both your Date instance and the database fields, you can easily mismatch the time zones creating the behavior that you are seeing. Try and display the java Date in UTC format, and look at your database date in UTC format, and see if they line up like you expect.
If it is a date format mismatch between the values passed from the code and the values expected in database then use SimpleDateFormat to change the format of the date values before passing on to databse
SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = dt.parse(iniDate);
Well, I have found the problem. As stated in Compare Date Java to DateTime Column in database table using SQL I was using the ".setDate" function to set the dates, such function truncates the time part, that was the problem. Now I'm using the ".setTimestamp" that uses both, date and time parts.
Thanks to all for your help, I have learned a lot about TimeZones!

How to select by date only if field is a timestamp?

I have a database field timestamp without timezone, that has values like 2015-11-23 14:42:55.278.
Now I want to find database records with just using the date part 2015-11-13.
Is that possible?
Ideally using hibernate and spring.
I'm not sure if is the best way in performace terms, but you may search dates between 2015-11-23 00:00:00.000 and 2015-11-23 23:59:59.999
If you want to fetch only for day 2015-11-13 then you can fetch all records using between keyword and by using timestamp of start of day.
dateField between 2015-11-13:<time_of_beginning_of_day> AND 2015-11-14:<time_of_beginning_of_next_day>
or
dateField between 2015-11-13:<time_of_beginning_of_day> AND 2015-11-13:<time_of_end_of_day>
You can cast the column to a date, e.g:
Postgres specific:
the_timestamp_column::date = date '2015-11-13'
or (standard SQL)
cast(the_timestamp_column as date) = date '2015-11-13'
You can also "reduce" the timestamp to different levels using date_trunc()
http://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC

Java: Insert into a table datetime data

I am trying to insert into a variable in MS- SQL database the current date and the time.
I use this format:
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Calendar cal = Calendar.getInstance();
System.out.println(dateFormat.format(cal.getTime()));
and I get this as a result 2013-01-28 09:29:37.941
My field in the database is defined datetime and as I have seen in other tables which have the same field, the date and the time is written exactly like this 2011-07-05 14:18:33.000.
I try to insert into the database with a query that I do inside a java program, but I get this error
SQL Exception: State : S0003 Message: The conversion of a varchar
data type to a datetime data type of the value is out of range. Error
: 242
My query is like that:
query = "INSERT INTO Companies CreatedOn"+
"VALUES ('" + dateFormat.format(cal.getTime()) + "')"
but I don't understand what I am doing wrong.
According to the error description, you are inserting an incorrect type into the database. See JDBC to MSSQL. You should convert Calendar to Timestamp.
Try using:
PrepareStatement statement
= connection.prepareStatement("INSERT INTO Companies CreatedOn VALUES(?)");
java.sql.Timestamp timestamp = new java.sql.Timestamp(cal.getTimeInMillis());
statement.setTimestamp(1, timstamp);
int insertedRecordsCount = statement.executeUpdate();
First of all, do NOT use string concatenation. Have you ever heart about SQL injection?
Correct way how to do that is to use prepared statement:
Idea is you define statement with placeholders and than you define value for those placeholders.
See #Taky's answer for more details.
dateFormat#format this method returns formatted string not Date object. Database field is DateTime and it is expecting java.sql.Timestamp to be inserted there not String according to docs.
To conform with the definition of SQL DATE, the millisecond values
wrapped by a java.sql.Date instance must be 'normalized' by setting
the hours, minutes, seconds, and milliseconds to zero in the
particular time zone with which the instance is associated.
Try java.sql.Timestamp object instead of String in query and I'd recommend you to use PreparedStatement.
This is because you are trying to save String date value to Date type DB field.
convert it to Data dataType
You can also use the datetime "unseparated" format yyyymmdd hh:mm:ss
You could use Joda framework to work with date/time.
It maps own date/time types to Hibernate/SQL types without problem.
When you set parameters in HQL query joda carries about right type mapping.
If you want to store current date and time then you should use MYSQL inbuilt method NOW().
for brief documentation refer http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html . so your code will be like.
INSERT INTO Companies CreatedOn VALUES(NOW())"
However If you want to do it using java Date-util then it should be
Calendar cal = Calendar.getInstance();
java.sql.Timestamp timestamp = new Timestamp(cal.getTimeInMillis());

Hibernate HQL and Date

I have a MySQL table with one of the column type as Date. In my hibernate mapping file I have mapped this column to type java.util.Date. Now in HQL while trying to retrieve objects based on date equality I do not get any results if I set the Date using new Date(). If I normalize the date by setting hours, minutes and seconds to zero I get results. Is this required since I have declared the SQL column type to be a Date and not Timestamp?
Try java.sql.Date
Hopefully this will help you out with the date equality issue.
RDJ
I was able to use java.util.Date with a SQL Server Date column by explicitly setting the #Type:
#Type(type="date")
public java.util.Date getDate() {
return date;
}
Without the annotation, I was getting
java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
with Hibernate 3.5.1-final

Categories