In our application we need to encrypt a column of table due to security demands, but this table has a lot of rows so we decided that we do this gradually over time. new entries come with encrypted value and old values will be migrated slowly. I'm doing this by adding a new column to table and via AttributeConverter/@Convert encryption/decryption is done.
public class AccountCard {
@Column(name = "card_number")
private String number;
@Column(name = "encrypted_card_number")
@Convert(converter = CardNumberConverter.class)
private String encryptedCardNumber;
}
In AccountCardRepository we have changed previous queries to search for both number and encryptedCardNumber like below:
@Query("""
SELECT a FROM AccountCard a
WHERE a.encryptedCardNumber = :cardNumber
OR a.number = :cardNumber
""")
AccountCard findByCardNumber(@Param("cardNumber") String cardNumber);
Spring data jpa does the transformation that is required for encryptedCardNumber which is very nice but problem is for number column the same transformed parameter is being set. By activating
org.hibernate.type.descriptor.sql: TRACE
logs are shown like this:
2022-09-20 00:28:09.059 TRACE 21768 --- [nio-8082-exec-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [UfcfN9potyyzs8pR3fyXxVL6SxLcLoaQUN5ZDr7nJ3Y=]
2022-09-20 00:28:09.060 TRACE 21768 --- [nio-8082-exec-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [VARCHAR] - [UfcfN9potyyzs8pR3fyXxVL6SxLcLoaQUN5ZDr7nJ3Y=]
As you see for both columns the encrypted value is being set. If I put 2 parameters for query things gets resolved but its ugly. like below:
@Query("""
SELECT a FROM AccountCard a
WHERE a.encryptedCardNumber = :cardNumber1
OR a.number = :cardNumber2
""")
AccountCard findByCardNumber(@Param("cardNumber") String cardNumber1, @Param("cardNumber2") String cardNumber2);
and call it with same card number.
How can I tell spring data that put encryptedValue for encryptedCardNumber and plain value for number
EDIT
Here is CardNumberConverter
public class CardNumberConverter implements AttributeConverter<String, String> {
@Override
public String convertToDatabaseColumn(String s) {
return AES.encrypt(s);
}
@Override
public String convertToEntityAttribute(String s) {
return AES.decrypt(s);
}
}