简体   繁体   中英

Get attribute name or column name in JPA converter

I have an entity with several double values where each has to be multiplied with a certain factor before storing it.

I would like to use a (single) JPA converter to multiply the attributes with the specific factor, but therefore I'd need to know which attribute I am converting within the converter function.

Is there a way to obtain the name of the attribute or the column name in the converter function or pass it to converter?

I don't know how your entity looks like but maybe the @Access annotation could be helpful - it can be used when you need to perform a simple transformation to the data when reading from or writing to the database (in this case the multipication happens through setter before save but getter gives the exact value stored in db). The inconvenience is that you need to add it on every setter that needs this conversion:

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

I suggest using entity lifecycle listeners instead of converters. Converters are reusable concept to map any Java datatype to a JPA type. They now nothing about your specific entity or a field. On the other hand, lifecycle listeners can be defined only for whole entity, therefore you must create listener per entity and design it in the way that the listener will know which fields to convert.

Entity listeners can be called for example before data from the entity is persisted (inserted), updated, or on the other side, also after the data is loaded back to the entity.

You would need to make use of at least @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 (you can use both @PrePersist and @PreUpdate on the same method).

Here is an example:

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

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM