通过hibernate的Joda-Money持久性

JodaTime有一个提供Hibernate持久性的库。 最近我开始关注Joda-Money并开始看看如何使用hibernate来保持它并且我没有看到任何库。

有什么建议么?

由于在Sudarshan的答案中链接到示例的链接被破坏,这里是org.joda.money.BigMoney的简单自定义用户类型的org.joda.money.BigMoney ,它将money对象保存在两列金额和货币中)以及如何使用它的示例。 它对org.joda.money.Money的作用相同。

 package test; import java.io.Serializable; import java.math.BigDecimal; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Currency; import org.apache.commons.lang.ObjectUtils; import org.hibernate.HibernateException; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.Type; import org.hibernate.usertype.CompositeUserType; import org.joda.money.BigMoney; import org.joda.money.CurrencyUnit; public class MoneyUserType implements CompositeUserType { private static final String[] PROPERTY_NAMES = {"amount", "currencyUnit"}; private static final Type[] PROPERTY_TYPES = {StandardBasicTypes.BIG_DECIMAL, StandardBasicTypes.CURRENCY}; public MoneyUserType() { super(); } public Object assemble(final Serializable cached, final SessionImplementor session, final Object owner) throws HibernateException { return cached; } public Serializable disassemble(final Object value, final SessionImplementor session) throws HibernateException { return (Serializable) value; } public String[] getPropertyNames() { return PROPERTY_NAMES.clone(); } public Type[] getPropertyTypes() { return PROPERTY_TYPES.clone(); } public Object getPropertyValue(final Object component, final int property) throws HibernateException { BigMoney money = (BigMoney) component; return (property == 0) ? money.getAmount() : money.getCurrencyUnit().toCurrency(); } public Object nullSafeGet(final ResultSet rs, final String[] names, final SessionImplementor session, final Object owner) throws HibernateException, SQLException { BigDecimal amount = StandardBasicTypes.BIG_DECIMAL.nullSafeGet(rs, names[0], session); Currency currency = StandardBasicTypes.CURRENCY.nullSafeGet(rs, names[1], session); return BigMoney.of(CurrencyUnit.of(currency), amount); } public void nullSafeSet(final PreparedStatement st, final Object value, final int index, final SessionImplementor session) throws HibernateException, SQLException { BigMoney money = (BigMoney) value; BigDecimal amount = (money == null) ? null : money.getAmount(); Currency currency = (money == null) ? null : money.getCurrencyUnit().toCurrency(); StandardBasicTypes.BIG_DECIMAL.nullSafeSet(st, amount, index, session); StandardBasicTypes.CURRENCY.nullSafeSet(st, currency, index + 1, session); } public Object replace(final Object original, final Object target, final SessionImplementor session, final Object owner) throws HibernateException { return deepCopy(original); } public void setPropertyValue(final Object component, final int property, final Object value) throws HibernateException { throw new HibernateException("Money is immutable."); } public Object deepCopy(final Object value) throws HibernateException { return (value != null) ? BigMoney.of(((BigMoney) value).getCurrencyUnit(), ((BigMoney) value).getAmount()) : null; } public boolean equals(final Object x, final Object y) throws HibernateException { return ObjectUtils.equals(x, y); } public int hashCode(final Object x) throws HibernateException { return ObjectUtils.hashCode(x); } public boolean isMutable() { return false; } public Class returnedClass() { return BigMoney.class; } } 

用法:

 @Type(type = "test.MoneyUserType") @Columns(columns = {@Column(name = "AMOUNT"), @Column(name = "CURRENCY")}) private BigMoney money; 

用户类型项目从版本3.0.0开始为joda-money 0.6提供支持。 但请注意,这需要Hibernate 4 。 目前的joda-money版本也是0.8

如果你想在Hibernate 3中使用它,请使用Sudarshan anwser中的示例(在撰写本文时它已被窃听)。

用户类型项目包括Joda Money支持。

好的,我接受了你的建议并为Joda图书馆中定义的Money创建了一个自定义类型,作为参考,人们可以在这里查找,在这里使用并在这里测试自定义类型

基于http://jadira.sourceforge.net

货币类型通常由货币和金额组成。 Jadira可以使用参数配置的货币仅将数量存储到数据库中。 例如:

 @Column @Type(type = "org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyAmount", parameters = {@org.hibernate.annotations.Parameter(name = "currencyCode", value = "USD")}) private Money money; Alternatively, with other types two columns to hold the amount an currency: @Columns(columns = { @Column(name = "MY_CURRENCY"), @Column(name = "MY_AMOUNT") }) @Type(type = "org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyAmountAndCurrency") private Money money; 

Joda-Money是非常新的,所以没有人为它提供Hibernate映射也就不足为奇了。

但是,编写自定义Hibernate类型适配器非常简单。 如果你查看JodaTime适配器的源代码,你会发现它们非常简单。 请参阅文档以了解如何编写自己的文档 。