Retain milliseconds in Oracle DB insert - java

I am trying to insert a record in a Oracle table using Java. The field in question is defined as a timestamp.
I am using a the following statement:
INSERT INTO MYTAB (UNIQUE_ID, CREATED_AT) VALUES ('137', ?)";
PreparedStatement updatePerf = connection.prepareStatement(updateString);
updatePerf.setTimestamp(1,getCurrentTimeStamp());
The getCurrentTimeStamp looks as follows:
private static java.sql.Timestamp getCurrentTimeStamp() {
long time = System.currentTimeMillis();
java.sql.Timestamp timestamp = new java.sql.Timestamp(time);
System.out.println("Time in milliseconds :" + timestamp);
return timestamp;
}
When the program runs, I still the correct timestamped printed with milliseconds:
Time in milliseconds :2014-05-13 15:40:03.076
However on the database, I only see
'137',2014-05-13 15:40:03
I want to retain the milliseconds desperately.

When you say "on the database, I only see", how are you getting the data out of Oracle? Have you proerly set NLS_TIMESTAMP?
Try setting:
NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH:MI:SS.FF'
in SQL*Plus, and then try the query, and see if you can see thw milliseconds component.
Alternately, you can format the timestamp column w/ a to_char() function:
select to_char(my_timestamp_col,'YYYY-MM-DD HH:MI:SS.FF') from my_table;
Note also, that if your column is timestamp with timezone, you'll need to set NLS_TIMETAMP_TZ_FORMAT instead.

Related

Insert jspinner time value to database

I have two jspinners. the one contains an HH:mm format and the other one is a simple number(int) spinner.
when SAVE button clicked I want to update a database table that contains the timeLimit (type time) and attempts (type int) columns. But I dont know how to save a jspinner value to a time type in my database.
String update = "Update qbank SET timeLimit = ? and attempts = ? where qbankID = ?";
preparedStatement = connection.prepareStatement(update);
preparedStatement.setTime(1, spinnerTime.getValue());
i tried the code above but the last part has an error saying spinnerTime.getValue is an object and setTime() requires a Time. How can I convert and object to time? or is there other way to insert a jspinner with time value to my database? any help would be appreciated!
It was just a simple overlooked problem. I just did this code.
Time time; int attempt;
time = (Time) spinnerTime.getValue();
attempt = Integer.parseInt(spinnerAttempt.getValue().toString());
String update = "Update qbank SET timeLimit = ? and attempts = ? where qbankID = ?";
preparedStatement = connection.prepareStatement(update);
preparedStatement.setTime(1, time);
preparedStatement.setInt(2, attempt);
preparedStatement.setInt(3, qbankID);
preparedStatement.executeUpdate();

Datetime is not inserted in table when executing the query through Java

I am using MySQL 5.5 and I am inserting datetime into my table through Java, using the query:
INSERT INTO player_sale(transaction_id,player_id,game_id,game_type_id,ticket_nbr,mrp_amt,deduct_from_bonus,deduct_from_deposit,deduct_from_winning,good_cause_amt,vat_amt,taxable_sale,transaction_date,is_cancel) VALUES(48160,1001501,1,2,0,1.0,0.0,1.0,0.0,0.0,0.0,1.0,'2015-07-09 18:45:01','N');
but the entry inserted is 0000-00-00 00:00:00 in the transaction_date column.
In addition to it, when I am executing the above query, through the query browser interface of MySQL, the correct datetime is inserted . The datatype of transacion_date is datetime.
I have dug out a lot of web, but I couldn't find the answer regarding the same.
I used the following java code :
try{
Timestamp transactionDate = new Timestamp(Calendar.getInstance().getTimeInMillis());
String query="INSERT INTO player_sale(transaction_id,player_id,game_id,game_type_id,ticket_nbr,mrp_amt,deduct_from_bonus,
deduct_from_deposit,deduct_from_winning,good_cause_amt,vat_amt,taxable_sale,transaction_date,is_cancel)
VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?);";
PreparedStatement pt = con.prepareStatement(query);
pt.setLong(1, 1);
pt.setLong(2, 110021);
pt.setInt(3, 1);
pt.setInt(4, 1);
pt.setLong(5, 12345678);
pt.setDouble(6, 10.00);
pt.setDouble(7, 20.00);
pt.setDouble(8,30.00);
pt.setDouble(9, 40.00);
pt.setDouble(10, 10.00);
pt.setDouble(11, 2.00);
pt.setDouble(12, 1.00);
pt.setTimestamp(13, transactionDate);
pt.setString(14, "N");
pstmt.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}

Hibernate - compare DateTime field with Restrictions.like

I have a createDateTime field with Date dataType in my entity class and hibernate generated a column with datetime type in the mysql table. Now, I need to compare createDateTime field with values without seconds. In fact, one user can enter for example 2015-01-01 12:10 in the search field and I want to show the record that has 2015-01-01 12:10:10 crateDateTime as a result. I know this is possible with flat query:
SELECT * FROM table_test WHERE crateDateTime LIKE "2015-01-01 12:10 %"
But I don't know how I can do this via hibernate.
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
data = formatter.parse("2015-01-01 12:10");
//This returned null.
Criterion crtmp = Restrictions.like("createDateTime", data);
//This returned ClassCastException. Because second argument must have "Date" dataType not "String"
Criterion crtmp = Restrictions.like("createDateTime", data + "%");
You should create a Date variable e.g. createDateTimePlusOneMinute, than find a time range between your createDateTime and createDateTimePlusOneMinute, using the following restrictions
criteria.add(Restrictions.ge("createDateTime", createDateTime));
criteria.add(Restrictions.lt("createDateTime", createDateTimePlusOneMinute));
// datetime comparison
Select c from Customer c where c.date<{d '2000-01-01'}

Unable to fetch result based on date range query

I want to fetch the record from HSQL database and query is as below:
ao.find(IssuesAD.class, Query.select().where("user=? AND (START_TIME = ? OR END_TIME = ? OR (convert(START_TIME,DATE) < convert(?,DATE) AND convert(END_TIME,DATE) > convert(?,DATE)) )",user,sqlDate,sqlDate))
// also tried by removing 'convert'
when i save or retrieve then i do convert java.util.date to java.sql.date format.
Above query works fine for retrieving the records match to exact date i.e. START_TIME=? or END_TIME=? but it does not work for date range (START_TIME < ? AND END_TIME > ?) even though records are existed.
In database records are existed as like - END DATE AS '2013-05-27 00:00:00.000000000', START DATE AS '2013-05-23 00:00:00.000000000'.
And parameter value is '2013-05-24' which between above record though unable to get retrieved in result.
Also, another records - END DATE AS '2013-05-30 00:00:00.000000000', START DATE AS '2013-05-23 00:00:00.000000000'.
And parameter value is '2013-05-28' and it should retrieve but did not..
Other stuff:
final java.sql.Date sqlDate = new java.sql.Date(startdatefield.getTime());
logger.info("final date sql date:" + sqlDate); //it prints as 2013-05-28
for (IssuesAD pi : ao.find(IssuesAD.class, Query.select().where("user=? AND (START_TIME = ? OR END_TIME = ? OR (convert(START_TIME,DATE) < convert(?,DATE) AND convert(END_TIME,DATE) > convert(?,DATE)) OR (convert(START_TIME,DATE) > convert(?,DATE) AND convert(END_TIME,DATE) < convert(?,DATE)))",user,sqlDate,sqlDate)))
{
....
}
In database - START_DATE and END_DATE both fields are type of "DATETIME".
Any idea what is wrong here...
Thanks

What's the right way to handle UTC date-times using Java, iBatis, and Oracle?

I'm coming up against an unexpected daylight savings time problem in code I thought was purely UTC. I'm using Java 1.6, the iBatis SQL mapper (2.3.3), and Oracle XE (an eval version of Oracle 10.2) with the Oracle thin driver.
The database contains a table that represents a television broadcast schedule. Each "Asset" (program) has a start_time and and end time. Here's the relevant slice:
create table Asset
(
asset_id integer not null, -- The unique id of the Asset.
[...]
start_time timestamp, -- The start time.
end_time timestamp, -- The end time.
[...]
constraint asset_primary_key primary key (asset_id),
constraint asset_time check (end_time >= start_time)
);
The oracle asset_time constraint is firing for programs that straddle the US central daylight savings time adjustment this upcoming Sunday morning, 11/1/2009.
I have this data transfer object (the Dates are java.util.Dates):
public class Asset
{
protected Long asset_id;
[...]
protected Date start_time;
protected Date end_time;
public Date getStart_time() { return start_time; }
public Date getEnd_time() { return end_time; }
public void setStart_time(Date start_time) { this.start_time = start_time; }
public void setEnd_time(Date end_time) { this.end_time = end_time; }
[...]
}
And in the iBatis SQL map I have this statement that inserts an Asset DTO into the Oracle Asset table:
<insert id="Asset.insert" parameterClass="com.acme.Asset">
insert into Asset
( asset_id, [...] start_time, end_time )
values
( #asset_id#, [...] #start_time#, #end_time# )
</insert>
On the Java side I've verified that I'm giving iBatis the correct UTC date input via this pre-insert assertion, which isn't thrown:
System.err.println("Inserting asset " + program_id);
System.err.println(" "+asset.getStart_time_str()+"--"+asset.getEnd_time_str());
if ( !asset.getEnd_time().after(asset.getStart_time())) {
System.err.println("Invalid datetime range in asset.");
throw new AssertionError("Invalid datetime range in asset.");
}
Just before the Oracle constraint failure the above code prints:
Inserting asset EP011453960004
2009-11-01T06:30:00Z--2009-11-01T07:00:00Z
I'm in the US central time zone, GMT -5:00, so this program starts at 1:30am and ends at 2:00am. The daylight savings change hits at 2:00am and turns the clock back to 1:00am.
iBatis reports the Oracle constraint failure (edited):
2009-10-30 22:58:42,238 [...] Executing Statement:
insert into Asset ( asset_id, [...] start_time, end_time )
values ( ?, [...] ?, ? )
2009-10-30 22:58:42,238 [...] Parameters:
[EP011453960004, [...] 2009-11-01 01:30:00.0, 2009-11-01 01:00:00.0]
2009-10-30 22:58:42,238 [..] Types:
[java.lang.Long, [...] java.sql.Timestamp, java.sql.Timestamp]
2009-10-30 22:58:42,285 [...] - Failed with a SQLException:
--- The error occurred in com/acme/data/dao/Asset-Write.xml.
--- The error occurred while applying a parameter map.
--- Check the Asset.insert-InlineParameterMap.
--- Check the statement (update failed).
--- Cause: java.sql.SQLException: ORA-02290: check constraint (ACME.ASSET_TIME)
violated
You'll notice that on the Oracle side, it's seeing the start_time/end_time with the daylight savings time adjustment, so something in the iBatis mapping logic or the Oracle driver isn't doing what I expected. The driver is ojdbc14.jar, the thin driver:
JDBCReadWrite.Driver = oracle.jdbc.OracleDriver
JDBCReadWrite.ConnectionURL = jdbc:oracle:thin:#localhost:1521:XE
What's the correct way to ensure that this code is purely UTC?
Thanks in advance!
I have a solution which seems to do the trick. Even though the application and the database used types that store time offsets from midnight on 1/1/1970 in GMT, the JDBC specification calls for applying an adjustment from/to the JVM's default timezone going in/out. And iBatis maps dates using the JDBC default. The adjustments were always symmetrical and therefore harmless as long as the data didn't cross a daylight savings time boundary, or if the machine or JVM were set to GMT by default.
As an experiment I switched the JVM default timezone to GMT:
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
and this solved the problem, though in a very heavy-handed way (other code in the JVM may not expect this).
But iBatis allows you to override the default type handling, at any level of granularity. I wrote a GMT-preserving type handler and registered it for all my java.util.Dates:
<typeHandler callback="com.acme.GMTDateTypeHandler" javaType="java.util.Date"/>
My type handler looks like this:
public class GMTDateTypeHandler implements TypeHandlerCallback
{
#Override
public void setParameter(ParameterSetter setter, Object parameter)
throws SQLException
{
java.util.Date date = (java.util.Date) parameter;
if ( date == null )
setter.setNull(Types.TIMESTAMP);
else
{
Timestamp timestamp = new Timestamp(date.getTime());
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
setter.setTimestamp(timestamp, calendar);
}
}
#Override
public Object getResult(ResultGetter getter) throws SQLException
{
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
return getter.getTimestamp(calendar);
}
#Override
public Object valueOf(String s)
{
throw new UnsupportedOperationException(
"GMTDateTypeHandler.valueOf() is not supported.");
}
}
Usually, Oracle converts date/time values from the client timezone to the server timezone, when storing data. And backwards, when reading it out again.
If you want the date/time values to be stored un-altered, you might want to use a variant of the timezone data type, the "TIMESTAMP WITH TIME ZONE Datatype", which lets you store the time zone with the value. You can find some info here in the
Oracle SQL data type doc. Just search for the "with timezone" part.

Categories