【问题标题】:Override @Column attribute value覆盖@Column 属性值
【发布时间】:2019-04-04 11:24:50
【问题描述】:

我有几个 POJO,它们都有金额。我的想法是创建一个通用对象MonetaryAmount(由货币和值组成),然后每当我想在我的一个 POJO 中表示货币金额时都会使用它:

public class MonetaryAmount {
    private String currency;
    private BigDecimal value;
}

public class Account {

    @Column(name = "ACCOUNT_NAME")
    private String name;

    private MonetaryAmount balance; // TODO set column annotation values of currency and value

}

由于MonetaryAmount 将在多个 POJO 中使用,我无法使用@Column 注释currencyvalue 属性,因为列名在所有情况下并不总是相同。有没有办法注释MonetaryAmount 属性(例如上面示例中的balance)以提供currencyvalue 属性的列名,以便jOOQ 在映射/取消映射类似于以下的POJO 时理解它们请问Hibernate如何解释@AttributeOverride注解?

【问题讨论】:

    标签: jpa jooq


    【解决方案1】:

    @Embeddable 注释目前 (jOOQ 3.11) 尚不受 jOOQ 的 DefaultRecordMapper 支持。相关的功能请求是:

    如果您没有在 POJO 上使用 JPA 注释,您现在可以做的就是在查询中使用以下别名表示法:

    ctx.select(
            ACCOUNT.ACCOUNT_NAME.as("name"),
            ACCOUNT.CURRENCY.as("balance.currency"),
            ACCOUNT.VALUE.as("balance.value"))
       .from(ACCOUNT)
       .fetchInto(Account.class);
    

    此功能记录在DefaultRecordMapper,请参阅:

    如果 Field.getName() 是 MY_field.MY_nested_field(区分大小写!),则该字段的值将被视为嵌套值 MY_nested_field,该值设置在传递给所有这些的嵌套 POJO 上(无论可见性如何):

    • 单参数实例方法 MY_field(...)
    • 单参数实例方法 myField(...)
    • 单参数实例方法 setMY_field(...)
    • 单参数实例方法 setMyField(...)
    • 非最终实例成员字段 MY_field
    • 非最终实例成员字段 myField

    【讨论】:

    • 感谢卢卡斯的回复。因此,如果我理解正确,DefaultRecordMapper 在类级别而不是在属性/成员级别检查注释,即如果一个成员正在使用注释,DefaultRecordMapper 假定所有成员都在这样做,对吗?另外,既然我已经在使用 JPA 注释了,请问还有其他选择吗?
    • @user1135357:是的。目标 POJO 类型是否带有 JPA 注释。混合这些行为太令人惊讶了。在存在@Table@Entity 注释的情况下,有一个待处理的功能请求使@Column 注释可选:github.com/jOOQ/jOOQ/issues/4586。我没有想到直接使用jOOQ API的替代方法。当然,您可以随时编写自己的RecordMapper 或使用第三方映射器,例如simpleflatmapper.org/0106-getting-started-jooq.html
    【解决方案2】:

    假设 Hibernate :您可以使用 Embedded 组件。

    @Entity
    public class Account implements Serializable{
    
        @Column(name = "ACCOUNT_NAME")
        private String name;
    
        @Embedded
        @AttributeOverrides( {
           @AttributeOverride(name="currency", column = @Column(name="CURRENCY") ),
           @AttributeOverride(name="value", column = @Column(name="VALUE") )
        } ) private MonetaryAmount balance;
    
    }
    
    @Embeddable
    public class MonetaryAmount implements Serializable{
        private String currency;
        private BigDecimal value;
    }
    

    虽然这应该可行,但我认为在您的情况下,您应该尝试继承并仍然使用相同的方法以面向对象的方式覆盖属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-28
      • 1970-01-01
      • 1970-01-01
      • 2013-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多