Encryption using keys based on a particular column value

We have a need of encrypting particular columns based not on some globally constant key, but based on a key associated to a particular row (e.g., a per-customer key). This means we cannot use ColumnTransformer: it does not get to see any other columns in the row, so it cannot choose the correct key to use for encryption for that column. Similarly, we can’t use PostLoad/PostPersist/PostUpdate very successfully, because decrypting the column also marks the entity as dirty, such that every read then turns into a write. I’d rather avoid polluting the model objects with as many Transient fields as we have encrypted fields to avoid making the object dirty.

Is there some way to hook into Hibernate’s own load/save flow so that we can transparently encrypt/decrypt entities on their way in & out of the database, using various keys depending on data found in columns other than the ones we’re encrypting, in a way that doesn’t mark the entity as dirty after loading? It does not appear that JPA directly offers us any suitable mechanism for doing what we’d like (short of having to use loads of Transient fields).

There is no way to do this because it’s not possible to access the state of other attributes in any way while transforming the value for one attribute. The only possible solutions that come to mind are:

  • Use transient fields and do the encryption/decryption in lifecycle listeners
  • Use a column transformer and fetch the encryption key in a SQL subquery somehow

How about augmenting Hibernate’s own behavior with our own customizations; i.e., through subclassing or the like? Any hope or possibilities there?

Well, you could extend the SingleTableEntityPersister and override the hydrate method to achieve this. If this is fine for you, see this documentation article about this: Hibernate ORM 5.5.2.Final User Guide

1 Like

Excellent! I think this is a good direction to explore. Thanks!