首页 > 解决方案 > 具有多个数据源的 Spring Boot JPA AttributeConverter

问题描述

我使用自定义属性转换器加密了 spring JPA Entity 数据。我在 Spring Boot 中使用单个(默认)postgres 数据源工作得很好。现在,当我实现多个数据源时,突然实体列加密/解密停止了。我不知道为什么属性转换器在多个数据源的情况下不起作用。

**Error:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: Error attempting to apply AttributeConverter; nested exception is javax.persistence.PersistenceException: Error attempting to apply AttributeConverter**

示例实体类代码:

@Entity
@Table(name="users")
@Data
public class User{

    @Id
    private String id;
    @Column(name="u_name")
    @Convert(converter = StringEncryptDecryptConverter.class)
    private String userName;
    @Column(name="u_contact")
    @Convert(converter = StringEncryptDecryptConverter.class)
    private String contact;
    @Column(name = "u_address")
    private String address;

}

StringEncryptDecryptConverter 类代码:

@Converter(autoApply = false)
public class StringEncryptDecryptConverter
extends AbstractEncryptDecryptConverter<String> {

    /**
     * Default constructor initializes with an instance of the
     * {@link CipherMaker} crypto class to get a {@link javax.crypto.Cipher}
     * instance
     */
    public StringEncryptDecryptConverter() {
        this(new CipherMaker());
    }

    /**
     * Constructor
     * 
     * @param cipherMaker
     */
    public StringEncryptDecryptConverter(CipherMaker cipherMaker) {
        super(cipherMaker);
    }

    @Override
    boolean isNotNullOrEmpty(String attribute) {
        return isNotEmpty(attribute);
    }

    @Override
    String convertStringToEntityAttribute(String dbData) {
        return dbData;
    }

    @Override
    String convertEntityAttributeToString(String attribute) {
        return attribute;
    }
}

应用程序属性:

spring.datasource.jdbcUrl=jdbc:postgresql://127.0.0.1:5432/test_Db
spring.datasource.username=postgres
spring.datasource.password=root

spring.another-datasource.jdbcUrl=jdbc:postgresql://127.0.0.1:5432/another_db
spring.another-datasource.username=postgres
spring.another-datasource.password=root*

标签: hibernatespring-bootmultiple-databases

解决方案


定义多个数据源时,您可以通过调用将包分配给相应的 EntityManager LocalContainerEntityManagerFactoryBean.setPackagesToScan(String... packagesToScan)。不太明显的是,您定义了 Hibernate 通常应该扫描哪些包,而不仅仅是实体。此 EntityManager 不存在这些包中没有的内容。对于应该使用此转换器的每个 EntityManager,您需要将您的转换器包添加到此列表中。

事后看来,这很明显,但不容易弄清楚。


推荐阅读