Setting AttributeConverter on a column changes @Query parameter and that parameter cant be reused

Viewed 39

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);
    }
}
0 Answers
Related