Hibernate @AttributeOverride嵌入的CompositeType

时间:2016-12-15 16:25:15

标签: java hibernate

我有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注释。

我已尝试过多种选择:

  1. Amountamount.amount(列名,如摘录中所示)
  2. amount.currencyCodeamount.valueamount.currency内的字段名称以及Amount
  3. getPropertyNames返回的值
  4. 只是CompositeUserTypeamount(导致AnnotationException:AttributeOverride.column()现在应该覆盖所有列)
  5. Hibernate似乎并不太关心点后面的内容。我可以将其更改为currencyCode并且不会抛出错误,所以我现在只是猜测,如何覆盖这些列名称。

    amount.abcdef不在Amount内时,即使在同一实体中多次使用,它也适用于此声明。

    Embeddable

    有人有想法吗? 我能找到的所有内容只与嵌入式内容有关,而与Embeddables内的CompositeUserTypes无关。

    我正在使用hibernate-5.1.2-final。

2 个答案:

答案 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生成的数据库是否具有预期的模式? 我希望这有帮助。目前无法创建示例。