Gosh that was sooo easy.
For anybody else, here's the scoop.
I want to create a Custom Data Type in PostgreSQL capable of storing a combination of local currency amount, currency code, exchange rate and base currency amount.
So in psql ...
Code:
CREATE TYPE mymoney AS (
local_value numeric(11,2),
mnemonic character(3),
exchange_rate numeric(11,2),
base_value numeric(11,2)
);
CREATE TABLE expense (id serial, amount mymoney);
To map this to Hibernate, the most important thing to do is make sure that the class for MyMoney implements org.postgresql.util.PGobject, overriding methods as necessary.
The mapping is done with
Code:
public class MoneyUserType implements UserType {
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner)
throws HibernateException, SQLException {
assert names.length == 1;
if (resultSet.wasNull()) {
return null;
}
final Money money = new Money(resultSet.getObject(names[0]).toString());
return money;
}
public void nullSafeSet(PreparedStatement statement, Object value, int index)
throws HibernateException, SQLException {
statement.setObject(index, value);
}
}
//NB This is an abbreviation of my actual class
So now I can simply do ...
Code:
Expense expense = new Expense();
expense.setAmount(new Money("(100,PHP,.90,111.11)"));
session.save(expense);
hbm.xml contains
Code:
<property name="amount" type="hibnoa.MoneyUserType">
<column name="price" sql-type="MONEY_TY"/>
</property>
I realise that by extending PGobject, I've made my code database dependent. Hopefully at some point the PostgreSQL JDBC driver will support SQLdata in which case there is a portable alternative available. In the meantime it would take all the wild horses in Argentina to make me change database so that's not really an issue.
best
Roy