与其处理货币字符串和金额,不如让 Hibernate 了解您的类型。这样你就可以:
private Money amount;
而不是
private BigDecimal amount;
private String currency;
所以你不需要到处转换。
我是这样做的:
1) 使用 JavaMoney 代替 JodaMoney,该 JSR-354 项目预计将包含在 Java 9 中。如果您想坚持使用 JodaMoney,则不需要下面的第 3 步。
2) 将此 UserType library 添加到您的类路径
3) 创建这个简单的类:
public class CustomPersistentMoneyAmountAndCurrency extends AbstractMultiColumnUserType<MonetaryAmount> {
private static final ColumnMapper<?, ?>[] COLUMN_MAPPERS = new ColumnMapper<?, ?>[] { new CustomStringColumnCurrencyUnitMapper(), new BigDecimalBigDecimalColumnMapper() };
private static final String[] PROPERTY_NAMES = new String[]{ "currency", "number" };
@Override
protected ColumnMapper<?, ?>[] getColumnMappers() {
return COLUMN_MAPPERS;
}
@Override
protected Money fromConvertedColumns(Object[] convertedColumns) {
CurrencyUnit currencyUnitPart = (CurrencyUnit) convertedColumns[0];
BigDecimal amountPart = (BigDecimal) convertedColumns[1];
return Money.of(amountPart, currencyUnitPart);
}
@Override
protected Object[] toConvertedColumns(MonetaryAmount value) {
return new Object[] { value.getCurrency(), value.getNumber().numberValue(BigDecimal.class) };
}
@Override
public String[] getPropertyNames() {
return PROPERTY_NAMES;
}
}
4) 现在,无论您想在您的实体中使用什么,您都可以这样做:
@TypeDefs(value = {
@TypeDef(name = "moneyAmountWithCurrencyType", typeClass = CustomPersistentMoneyAmountAndCurrency.class)
})
@Entity
@Table(name = "account_entry")
public class AccountEntry {
private Money referenceMoney;
...
@Basic( optional = false )
@Columns(columns = {
@Column( name = "reference_money_currency", nullable = false, length = 3 ),
@Column( name = "reference_money", nullable = false )
})
@Type(type = "moneyAmountWithCurrencyType")
public Money getReferenceMoney() {
return this.referenceMoney;
}
}
就是这样。您将在整个过程中获得强大的打字。