2011-11-27 15 views

risposta

5

Va bene ho seguito il tuo consiglio e cucinato un tipo personalizzato prezzo, come definito nella Biblioteca Joda, come un popolo di riferimento può guardare in su here, l'uso qui e test per il tipo personalizzato here

+0

Penso che la tua implementazione abbia un errore in 'setPropertyValue()' - Gli oggetti Money sono immutabili, e 'money.withAmount (valore (BigDecimal))' semplicemente crea un nuovo oggetto –

+0

Il punto rilevato ha apportato la modifica :), Tuttavia I Non sono sicuro che il metodo setPropertyValue() venga chiamato da hibernate in base alla mia analisi, solo il metodo nullSafeSet sembra essere chiamato da hibernate. – Sudarshan

+0

Umm ... sei consapevole che stai solo cambiando la variabile locale? Penso che l'unico modo corretto per implementare questo metodo per un oggetto immutabile sia quello di lanciare unsupportedOperationException.Forntunately, come dici tu, non sembra essere chiamato. –

1

Joda-Money è molto nuovo, quindi non sorprende che nessuno abbia già fornito una mappatura Hibernate.

Tuttavia, la scrittura di adattatori di tipo Hibernate personalizzati è piuttosto semplice. Se osservi la fonte degli adattatori JodaTime, vedrai che sono davvero semplici. Vedere lo docs per come scrivere il proprio.

+0

Qualsiasi libreria di denaro che conosci e che ha compatibilità con l'ibernazione? in termini di adattatori – Sudarshan

+3

Ok ho preso il tuo consiglio e ho preparato un tipo personalizzato per Money come definito nella libreria Joda, come persone di riferimento possono cercarlo [http://code.google.com/p/ddd -cqrs-base-project/source/browse/trunk/src/main/java/org/nthdimenzion/ddd/domain/sharedkernel/MoneyType.java), utilizzo [qui] (http://code.google.com/pp /ddd-cqrs-base-project/source/browse/trunk/src/main/java/com/librarymanagement/domain/Book.java) e prova per il tipo personalizzato [qui] (http://code.google.com /p/ddd-cqrs-base-project/source/browse/trunk/src/test/java/integration/com/librarymanagement/BookTest.java) – Sudarshan

+1

Il commento di Sudarshan dovrebbe essere promosso a una risposta (se può essere?) IMO . – Rich

4

Il progetto User Type fornisce supporto per joda-money 0.6 dalla versione 3.0.0. Si prega di notare, tuttavia, che ciò richiede Hibernate 4. Anche l'attuale versione joda-money è 0.8

Se vuoi usarlo con Hibernate 3 usa l'esempio in Sudarshan anwser (è bugged al momento della scrittura).

+0

Penso che questa sia la migliore risposta ora. – LaurentG

5

Poiché il collegamento all'esempio nella risposta di Sudarshan è interrotto, ecco un'implementazione di un semplice tipo di utente personalizzato per org.joda.money.BigMoney, che persiste in oggetti di denaro in due colonne importo e valuta) e un esempio di come utilizzarlo. Funziona allo stesso modo per 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; 
    } 
} 

Usage:

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

Based on http://jadira.sourceforge.net

Tipi denaro consistono tipicamente di una moneta e la quantità. Jadira consente di memorizzare solo l'importo nel database con la valuta configurata utilizzando un parametro. Ad esempio:

@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; 
+0

grazie per questo;) – micdcar