Joda-Money настойчивость в спящем режиме

Существует библиотека для JodaTime, которая обеспечивает постоянство Hibernate. Недавно я начал смотреть на Joda-Money и начал видеть, как это можно сохранить с помощью hibernate, и я не вижу никакой библиотеки.

Какие-либо предложения?

6 ответов

Решение

Хорошо, я воспользовался вашим советом и подготовил пользовательский тип для денег, как это определено в библиотеке Joda, в качестве справки люди могут посмотреть его здесь, использовать здесь и проверить здесь пользовательский тип.

Поскольку ссылка на пример в ответе Сударшана не работает, здесь приведена реализация простого пользовательского типа для org.joda.money.BigMoney, который сохраняет денежные объекты в двух столбцах сумма и валюта) и пример того, как его использовать. Это работает так же для 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;

Проект User Type включает поддержку Joda Money.

Проект User Type обеспечивает поддержку joda-money 0.6 с версии 3.0.0. Обратите внимание, однако, что для этого требуется Hibernate 4. Также текущая версия joda-money - 0.8

Если вы хотите использовать его с Hibernate 3, используйте пример в Sudarshan anwser (он содержит ошибки во время написания).

http://jadira.sourceforge.net/usertype-userguide.html

Типы денег обычно состоят из валюты и суммы. 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, вы увидите, что они действительно просты. См. Документы о том, как написать свой собственный.

Другие вопросы по тегам