After lots of reading I realized this is actually a bug with Oracle 8i, the workaround I used is this (of course the best solution is upgrade your oracle):
1. Map your dates as timestamp and tell hibernate to ignore your fields for insert and update:
Code:
<property name="myDate" type="timestamp" column="myDate" insert="false" update="false"/>
2. Update your date normally:
Code:
myPojo.setField1(...);
myPojo.setField2(...);
myPojo.setMyDate(new java.util.Date());
3. Update in the database manually:
Code:
myPojo.saveMyDate(session);
where saveMyDate() is something like this:
Code:
public void saveMyDate(org.hibernate.Session session) throws java.sql.SQLException
{
java.sql.Connection conn = session.connection();
java.sql.Statement stmt = conn.createStatement();
try {
String s = "update MyPojo set myDate=" + Misc.toOracleDateTime(expirationDate) + " where id_myPojo=" + getId_myPojo();
stmt.executeUpdate(s);
} finally {
stmt.close();
}
}
your java.sql.Connection comes from session.connection() so you can be sure your update belongs to the same transaction as your hibernate session.
Misc.toOracleDateTime() is just a static method that returns a "to_date()" oracle call:
Code:
public static String toOracleDateTime(java.util.Date d)
{
if (d == null)
return "null";
Calendar c = Calendar.getInstance();
c.setTime(d);
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH) + 1;
int day = c.get(Calendar.DATE);
int hour = c.get(Calendar.HOUR_OF_DAY);
int min = c.get(Calendar.MINUTE);
int sec = c.get(Calendar.SECOND);
StringBuffer sb = new StringBuffer(55);
sb.append("TO_DATE('");
sb.append(Misc.formatInt(day, '0', 2));
sb.append("/");
sb.append(Misc.formatInt(month, '0', 2));
sb.append("/");
sb.append(Misc.formatInt(year, '0', 4));
sb.append(" ");
sb.append(Misc.formatInt(hour, '0', 2));
sb.append(":");
sb.append(Misc.formatInt(min, '0', 2));
sb.append(":");
sb.append(Misc.formatInt(sec, '0', 2));
sb.append("', 'DD/MM/YYYY HH24:MI:SS')");
return sb.toString();
}
Misc.formatInt() is a simple method to covert an int to a string with 0's to the left.
If your pojo is a new object you need to flush your session to guarantee it will be inserted before you update, otherwise you will try to update an object not yet written in db:
Code:
MyPojo p = new MyPojo();
...
session.save(p);
session.flush();
p.saveMyDate(session);
I'm sure there must be more elegant ways to do this but it was a fast solution for me and now that I'm running oracle 9 don't need to do this anymore...