Anm*_*pta 5 java persistence hibernate
我正在使用休眠来保留我的数据。这是一个财务应用程序,我很难保留该应用程序的最基本实体“金钱”。我使用的是JodaMoney,但它是不可变的,因此无法找到持久的方法。而且,如果没有将我的钱花在数据库上,就没有必要编写该应用程序。当我什至无法存储对象状态时,如何处理不变性?然后,我开始创建自己的'Money'(字段为BigDecimal量,而java.util.Currency为货币字段),我想使用java.util的'Currency'。但是,由于没有公共构造函数,因此休眠不能持久化。请指导我如何处理?
EDIT1:最基本的类的代码:
@Entity
public class BasicMoney {
@Embedded
@Id
private BigDecimal amount;
@Embedded
private Currency currency;
//getters and setters, other methods
}
Run Code Online (Sandbox Code Playgroud)
现在,当我创建此类的对象并尝试将其存储到数据库中时,它将不起作用。Hibernate抛出org.hibernate.InstantiationException:没有默认的实体构造函数:java.util.Currency。因此,这就是我面临的问题。
您可以使用解决方法
@Embedded
String currency; //store data as a string
public void setCurrency(Currency currency) {
this.currency = currency.getCurrencyCode(); //conversion to an actual currency
}
public Currency getCurrency() {
return Currency.getInstance(currency); //conversion to an actual currency
}
Run Code Online (Sandbox Code Playgroud)
Hibernate 本身支持 java.util.Currency。 https://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/types.html#types-basic-value-currency
与其处理货币字符串和金额,不如教 Hibernate 了解您的类型。这样你就会有:
private Money amount;
Run Code Online (Sandbox Code Playgroud)
代替
private BigDecimal amount;
private String currency;
Run Code Online (Sandbox Code Playgroud)
所以你不需要到处转换。
这是我的方法:
1) 使用JavaMoney代替JodaMoney,该 JSR-354 项目预计将包含在 Java 9 中。如果您想坚持使用 JodaMoney,则不需要下面的第 3 步。
2) 将此UserType 库添加到您的类路径
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;
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
就是这样。您将在整个过程中获得强大的打字能力。
| 归档时间: |
|
| 查看次数: |
6228 次 |
| 最近记录: |