我有Amount
通过CompositeUserType
映射到两个数据库列:
public class Amount {
private BigDecimal value;
private CurrencyCode currency;
}
在Embeddable
中使用它:
@Embeddable
public class AccountBalance {
private Calendar date;
@Type(type = Amount.TYPE_DEF)
@Columns(columns = {
@Column(name = "amount"),
@Column(name = "currencyCode")})
private Amount amount;
}
这里嵌入了多次:
public class AccountStatement
@AttributeOverrides(value = {
@AttributeOverride(name = "date", column = @Column(name = "openingBalanceDate") ),
@AttributeOverride(name = "amount.amount", column = @Column(name = "openingBalanceAmount") ),
@AttributeOverride(name = "amount.currencyCode", column = @Column(name = "openingBalanceCurrency") )})
@Embedded
@Basic(optional = true)
private AccountBalance openingBalance;
@AttributeOverrides(value = {
@AttributeOverride(name = "date", column = @Column(name = "closingBalanceDate") ),
@AttributeOverride(name = "amount.amount", column = @Column(name = "closingBalanceAmount") ),
@AttributeOverride(name = "amount.currencyCode", column = @Column(name = "closingBalanceCurrency") )})
@Embedded
@Basic(optional = true)
private AccountBalance closingBalance;
结果是:
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: ...AccountStatement column: amount (should be mapped with insert="false" update="false")
当我将updatable = false, insertable = false
添加到AccountBalance
中的两列(如异常文本中所示)时,架构验证成功,但是在插入数据时失败,因为它尝试插入{{ 1}}进入BigDecimal
中的下一个字段(我的摘录中未显示),这是一个日期。
所以我希望值可以插入和更新。
这导致hibernate无法正确处理PreparedStatement
两列的AttributeOverrides
注释。
我已尝试过多种选择:
Amount
和amount.amount
(列名,如摘录中所示)amount.currencyCode
和amount.value
(amount.currency
内的字段名称以及Amount
getPropertyNames
返回的值
CompositeUserType
和amount
(导致AnnotationException:AttributeOverride.column()现在应该覆盖所有列) Hibernate似乎并不太关心点后面的内容。我可以将其更改为currencyCode
并且不会抛出错误,所以我现在只是猜测,如何覆盖这些列名称。
当amount.abcdef
不在Amount
内时,即使在同一实体中多次使用,它也适用于此声明。
Embeddable
有人有想法吗? 我能找到的所有内容只与嵌入式内容有关,而与Embeddables内的CompositeUserTypes无关。
我正在使用hibernate-5.1.2-final。
答案 0 :(得分:2)
我已经向Hibernate提交了一个拉取请求,最近合并了,这将允许它工作: https://hibernate.atlassian.net/browse/HHH-11465
此修补程序的工作方式,您需要指定两次相同的覆盖名称,因此在您的示例中它将是:
@AttributeOverrides(value = {
@AttributeOverride(name = "date", column = @Column(name = "openingBalanceDate") ),
@AttributeOverride(name = "amount", column = @Column(name = "openingBalanceAmount") ),
@AttributeOverride(name = "amount", column = @Column(name = "openingBalanceCurrency") )})
@Embedded
@Basic(optional = true)
private AccountBalance openingBalance;
(订单必须与CompositeUserType
中的订单相同。)
现在已经合并了,所以它将在Hibernate 5.2的下一个版本中发布,它将是5.2.11。
答案 1 :(得分:0)
在hibernate guide之后,您应该将@Embeddable
添加到AccountBalance
。
此外,我建议将@Embeddable用于Amount
。否则你混淆了概念。
您是否检查过hibernate生成的数据库是否具有预期的模式?
我希望这有帮助。目前无法创建示例。