tags:

views:

190

answers:

2

I'm working on a java project full of Hibernate (3.3.1) mapping files that have the following sort of declaration for most domain objects.

<property name="dateCreated" generated="insert">
     <column name="date_created" default="getdate()" />
</property>

The problem here is that getdate() is an MSSQL specific function, and when I'm using something like H2 to test subsections of the project, H2 screams that

getdate() 

isn't a recognized function. It's own timestamping function is

current_timestamp(). 

I'd like to be able to keep working with H2 for testing, and wanted to know whether there was a way of telling Hibernate "use this database's own mechanism for retrieving the current timestamp". With H2, I've come up with the following solution.

CREATE ALIAS getdate AS $$ java.util.Date now() { return new java.util.Date(); } $$;
CALL getdate();

It works, but is obviously H2 specific.

I've tried extending H2Dialect and registering the function getdate(), but that doesn't seem to be invoked when Hibernate is creating tables. Is it possible to abstract the idea of a default timestamp away from the specific database engine?

+1  A: 

Have you tried using a <timestamp> mapping inside your <class>?

The docs aren't very clear but it sounds like this should result in mapping a column whose value is a timestamp.

You can specify if Hibernate should use a database generated value by setting either generated="insert" or generated="always".

matt b
The generated property doesn't actually do any of the generation (I've tried it). From the doc you referenced: "When Hibernate issues an SQL INSERT or UPDATE for an entity that has defined generated properties, it immediately issues a select afterwards to retrieve the generated values."This assumes that the database has already been configured to do the generation. We're already using the timestamp mapping, but it's updated whenever the object is accessed by Hibernate, not simple when it's been created.
unsquared
Ah, I thought by "generated" the doc meant "generated by a database-specific function" that the dialect would know of.
matt b
Yeah. I assumed the same and was in the process of ditching all those getdate() functions when I actually tried it and saw all my columns set to NULL. This would be a handy spot for a disclaimer in the Hibernate documentation.
unsquared
+1  A: 

Could you try the following (without generated since your database is not generating the value):

<column  name="DATE_CREATED" sql-type="timestamp"  default="CURRENT_TIMESTAMP"/>
Pascal Thivent
I could. My point isn't that I'd like to switch entirely over to H2, but that I'm testing small sections of code where I really don't need to use MSSQL, and where using an in-memory DB like H2 makes my testing that much quicker and more enjoyable. Having a different name for a timestamping function in every DBMS feels silly.
unsquared
HSQLDB is very similar to H2 (never used H2 so I don't know the breakdown in features exactly) and supports `CURRENT_TIMESTAMP`. I use HSQL all the time for in-memory unit testing. http://hsqldb.org/doc/2.0/guide/sqlgeneral-chapt.html#N10544
matt b
@unsquared: I'm not 100% sure but I think the above suggestion is portable.
Pascal Thivent
@matt: Yeah, but I'm talking H2 vs. MSSQL, not H2 vs. HQL
unsquared
@unsquared, right, but CURRENT_TIMESTAMP is valid in both MSSQL and HSQL.
matt b
@matt: Bloody hell. CURRENT_TIMESTAMP works. Thanks.
unsquared
@pascal: Thank you as well. I don't know how I missed this solution myself.
unsquared