在 JPA 转换器中获取属性名或列名

Get attribute name or column name in JPA converter

我有一个包含多个双精度值的实体,其中每个值都必须乘以某个因子才能存储。

我想使用(单个)JPA 转换器将属性与特定因子相乘,但因此我需要知道我在转换器函数中转换的是哪个属性。

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

我不知道你的实体是什么样子,但也许 @Access 注释可能会有帮助 - 当你需要在读取或写入数据库时​​对数据执行简单转换时可以使用它(在在这种情况下,乘法运算在保存之前通过 setter 发生,但 getter 给出了存储在 db 中的确切值)。不便之处在于您需要在需要此转换的每个 setter 上添加它:

@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;
    }
}

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

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

您至少需要使用 @PrePersist, which would trigger your method before your new entity is inserted into the database - in such method you have chance to multiply your data or do whatever you want. The chance is that, when the entity is read from database, you also want to convert data from database to the initial form you had before persisting. Then you should also use @PostLoad to convert back the data. And finally, if you want to apply the conversion again also on updates, you should use @PreUpdate(您可以在同一方法上同时使用 @PrePersist@PreUpdate)。

这是一个例子:

@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;
  }

}