2015-09-23 84 views
1

我有一个具有多个double值的实体,每个值在存储之前都必须乘以某个因子。我想使用(单)JPA转换器乘以具体因素的属性,但因此我需要知道我在转换器功能内转换哪个属性。在JPA转换器中获取属性名称或列名称

有没有办法在转换器函数中获取属性名称或列名称或将其传递给转换器?

+0

PS:我也想感谢的替代战略,以实现所需的行为不破坏抽象的建议。目前我正在研究AOP,但我不确定这是否是一个好主意。 – Tobson

+1

您可以为所需的属性创建自己的注释,并在持久化之前读取实体中的元数据。 –

回答

1

我不知道你的实体是怎么样的,但也许@Access注释可能会有所帮助 - 当你需要对数据进行简单的数据转换(在这个数据库中读取或写入数据时)如果保存前通过setter发生乘法,但getter给出存储在db中的确切值)。不便之处在于你需要增加它在每个需要这种转换二传手:

@Entity 
@Access(AccessType.FIELD) 
public class Item { 

    private static final long FACTOR = 5; 

    @Id 
    private long id; 

    private String name; 

    @Transient 
    private long amount; 

    // getter and setters for id and name 

    @Access(AccessType.PROPERTY) 
    public long getAmount() { 
     return amount; 
    } 

    public void setAmount(long amount) { 
     this.amount = amount * FACTOR; 
    } 
} 
+0

这比我希望的更麻烦,但我想这是最好的方法。 – Tobson

1

我建议使用,而不是转换器的实体lifecycle listeners。转换器是可重用的概念,可将任何Java数据类型映射到JPA类型。他们现在没有关于你的具体实体或领域。另一方面,只能为整个实体定义生命周期侦听器,因此您必须为每个实体创建侦听器,并按侦听器知道要转换的字段的方式进行设计。

实体监听器可以在数据加载回实体之前调用,例如在实体的数据被持久(插入),更新或在另一侧之前。

您需要至少使用@PrePersist,这会在您的新实体插入数据库之前触发您的方法 - 在这种方法中,您有机会乘数或做任何你想做的事。有可能是,当从数据库中读取实体时,您还希望将数据库中的数据转换为持续之前的初始形式。那么你也应该使用@PostLoad来转换回数据。最后,如果您想要在更新时再次应用转换,则应该使用@PreUpdate(您可以在同一方法上使用@PrePersist和​​)。

下面是一个例子:

@Entity 
public class Item { 
    @Id 
    private long id; 

    // this value will be multiplied by 10 when stored in DB 
    private long size; 
    // this value will be multiplied by 2 when stored in DB 
    private long amount; 

    @PrePersist 
    @PreUpdate 
    public void convertToDbFormat() { 
    size = size * 10; 
    amount = amount * 2; 
    } 

    @PostLoad 
    public void convertFromDbFormat() { 
    size = size/10; 
    amount = amount/2; 
    } 

} 
+0

Thx为伟大的解释! – Tobson