试试这个:
@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
@Type(type = "org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyAmount",
parameters = {@org.hibernate.annotations.Parameter(name = "currencyCode", value = "USD")})
效果很好,但我希望将货币存储在数据库中,并且能够使用不同的货币。
答案 0 :(得分:4)
@Entity
@Table(name = "moneyAmountAndCurrency")
@TypeDef(name = "testjoda_MoneyAmountWithCurrencyType", typeClass = PersistentMoneyAmountAndCurrency.class)
public class MoneyAmountAndCurrencyHolder implements Serializable {
private static final long serialVersionUID = -1674416082110551506L;
@Columns(columns = { @Column(name = "MY_CURRENCY"), @Column(name = "MY_AMOUNT") })
@Type(type = "testjoda_MoneyAmountWithCurrencyType")
private Money money;
答案 1 :(得分:3)
这实际上与Chris Pheby给出的答案没有什么不同。我只是在没有@TypeDef
s等的情况下提供他的答案的版本,用于两个场景:
CHAR(3)
,以便人们使用3-letter ISO-4217 code SMALLINT
,以便使用3-digit ISO-4217 number 在这两种情况下,Money
字段的数量组件都存储为DECIMAL(9,2)
,大多数RDBMS需要5个字节的存储空间。当然,您可以使用任何其他确切的数据类型,以避免double
/ float
附带的精确问题。
我的虚构Payment
@Entity
对于方案(1)看起来像这样:
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
}
}
静态方法只是在将此类对象提交到持久性存储之前实例化它的一个示例。
数据库的相应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),您只需修改@Type
字段的paidMoney
注释即可阅读PersistentMoneyAmountAndCurrencyAsInteger
而不是PersistentMoneyAmountAndCurrency
(区别在于<类名称中的strong> AsInteger 后缀。
// :
// :
@Type(type = "org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyAmountAndCurrencyAsInteger")
private Money paidMoney;
// :
// :
所有剩余的代码(甚至是静态方法中Money
对象的实例化)都保持不变。
然后你会得到以下DDL和Hibernate生成的相应INSERT
语句(978
是joda money为你自动计算的EUR
的数字代码)
CREATE TABLE Payment (
paidMoneyCurrency SMALLINT NOT NULL,
paidMoneyAmount DECIMAL(9,2) NOT NULL
);
INSERT INTO Payment (paidMoneyCurrency, paidMoneyAmount) VALUES (978, 1234.56);