Java 如何在Hibernate中将Joda Money映射为org.jadira.usertype.Money和currency.Joda.persistentMoneyAmount和currency类型?

Java 如何在Hibernate中将Joda Money映射为org.jadira.usertype.Money和currency.Joda.persistentMoneyAmount和currency类型?,java,hibernate,joda-money,Java,Hibernate,Joda Money,试一试: @Type(type = "org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyAmountAndCurrency") private org.joda.money.Money price; 得到这个: org.hibernate.MappingException: property mapping has wrong number of columns:domain.ClientOrderItem.price type:

试一试:

@Type(type = "org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyAmountAndCurrency")
private org.joda.money.Money price;
得到这个:

org.hibernate.MappingException: property mapping has wrong number of columns:domain.ClientOrderItem.price type: org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyAmountAndCurrency


工作很好,但我想在数据库中存储货币,并能够使用不同的货币。

中有一个工作示例

介绍 事实上,这与作者给出的答案没有什么不同。我只是提供了他的答案的一个版本,没有
@TypeDef
s等,用于两个场景:

  • Currency在MySQL中存储为
    CHAR(3)
    ,以便使用
  • Currency在MySQL中存储为
    SMALLINT
    ,使用
  • 在这两种情况下,
    Money
    字段的amount组件存储为
    十进制(9,2)
    ,对于大多数RDBMS,这需要5字节的存储空间。当然,您可以使用任何其他精确的数据类型,以避免
    double
    /
    float
    可能带来的精度问题

    情景1(三个字母的货币表示) 我虚构的
    支付
    @实体
    在场景(1)中如下所示:

    静态方法只是在将对象提交到持久性存储之前实例化此类对象的一个示例

    数据库对应的DDL如下所示:

    CREATE TABLE Payment (
        paidMoneyCurrency CHAR(3) NOT NULL,
        paidMoneyAmount DECIMAL(9,2) NOT NULL
    );
    
    Hibernate生成的
    INSERT
    语句如下所示:

    INSERT INTO Payment (paidMoneyCurrency, paidMoneyAmount) VALUES ('EUR', 1234.56);
    
    情景2(三位数货币表示) 对于场景(2),您只需修改
    paidMoney
    字段的
    @Type
    注释,即可将其读取为
    PersistentMoneyAmountandCurrencySinteger
    ,而不是
    PersistentMoneyAmountandCurrencySinteger
    (区别在于类名中的AsInteger后缀)

    所有剩余的代码(即使是静态方法中
    Money
    对象的实例化)都保持不变

    然后您将得到以下DDL和Hibernate生成的相应的
    INSERT
    语句(
    978
    是joda money为您自动计算的
    EUR
    的数字代码)

    package com.fictional;
    
    import org.hibernate.annotations.Columns;
    import org.hibernate.annotations.Type;
    import org.joda.money.CurrencyUnit;
    import org.joda.money.Money;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    
    /**
     * A fictional payment.
     */
    @Entity
    public class Payment {
    
        /**
         * Paid money.
         */
        @Columns(columns = {@Column(name = "paidMoneyCurrency"), @Column(name = "paidMoneyAmount")})
        @Type(type = "org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyAmountAndCurrency")
        private Money paidMoney;
    
    
        /**
         * Sample construction of a money object belonging to a payment.
         */
        static public void testPayment()
        {
            Payment p = new Payment();
    
            p.paidMoney = Money.of(CurrencyUnit.EUR, 1234.56);
    
            // Hibernate persistence code to insert the new record
        }
    }
    
    CREATE TABLE Payment (
        paidMoneyCurrency CHAR(3) NOT NULL,
        paidMoneyAmount DECIMAL(9,2) NOT NULL
    );
    
    INSERT INTO Payment (paidMoneyCurrency, paidMoneyAmount) VALUES ('EUR', 1234.56);
    
        // :
        // :
        @Type(type = "org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyAmountAndCurrencyAsInteger")
        private Money paidMoney;
        // :
        // :
    
    CREATE TABLE Payment (
        paidMoneyCurrency SMALLINT NOT NULL,
        paidMoneyAmount DECIMAL(9,2) NOT NULL
    );
    
    INSERT INTO Payment (paidMoneyCurrency, paidMoneyAmount) VALUES (978, 1234.56);