如何使用 Spring + Hibernate 对实体进行自定义验证以进行多租户设置

Posted

技术标签:

【中文标题】如何使用 Spring + Hibernate 对实体进行自定义验证以进行多租户设置【英文标题】:How to do custom validation on entity for multitenant setup using Spring + Hibernate 【发布时间】:2021-03-12 05:22:08 【问题描述】:

我正在尝试使用 spring hibernate 在多租户设置中使用自定义 ConstraintValidator 实现来验证实体的字段。 我们如何让自定义验证器租户知道?验证器中的实体管理器和其他自动装配的 bean 始终为空。

实体类:

@Entity
@Table(name = "autoupdate_json")
public class AutoupdateJson 

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

@Column(name="autoupdate_id")
private String autoupdateId; 

@Column(name="deployment_json", length=10000)
@ValidateAutodeploymentConfig
@Convert(converter=JpaConverterJson.class)
private ApplyInputJson deploymentJson; 

` 验证注解:

@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = AutodeploymentConfigValidator.class)
public @interface ValidateAutodeploymentConfig 

String message() default "One or More of the Devices already have perpetual mode settings enabled. Please cancel the existing "
        + " deployment config to add a new one, Updates are not supported. ";

Class<?>[] groups() default ;

Class<? extends Payload>[] payload() default ;

验证器实现:

public class AutodeploymentConfigValidator
    implements ConstraintValidator<ValidateAutodeploymentConfig, ApplyInputJson> 

@PersistenceContext
EntityManager entityManager; 

@Autowired
DeviceRepository deviceRepository; 

@Override
public boolean isValid(ApplyInputJson value, ConstraintValidatorContext context) 
    List<String> deviceSerialNumbers = Arrays.asList(value.getDevices().getSerial());
    
    System.out.println("entityManager: " + entityManager);
    System.out.println("repo bean: " + deviceRepository);

两个系统输出都是空的。

【问题讨论】:

【参考方案1】:

实体管理器和设备存储库为空,因为 AutodeploymentConfigValidator 不是来自 Spring 上下文。 它是由hibernate使用的默认约束验证工厂创建的,它不使用arg构造函数。

尝试添加HibernatePropertiesCustomizer 来告诉hibernate 使用哪个验证工厂。比如:

@Component
public class HibernateCustomizer implements HibernatePropertiesCustomizer 

    private final ValidatorFactory validatorFactory;

    public HibernateCustomizer(ValidatorFactory validatorFactory) 
        this.validatorFactory = validatorFactory;
    

    public void customize(Map<String, Object> hibernateProperties) 
        hibernateProperties.put("javax.persistence.validation.factory", validatorFactory);
    

有了这个,你应该能够在你的约束验证器中使用实体管理器。

【讨论】:

以上是关于如何使用 Spring + Hibernate 对实体进行自定义验证以进行多租户设置的主要内容,如果未能解决你的问题,请参考以下文章

使用 Hibernate + Spring 进行缓存 - 一些问题

对使用 Spring 和 Hibernate 的 Java 日志系统感到困惑

使用 Spring Boot + Hibernate + MySql 运行 MVC 应用程序

使用 Hibernate 的 Spring Security 3 数据库身份验证

Spring框架学习spring整合hibernate

我们如何使用hibernate作为orm单独的数据库和模式来构建一个spring mvc多租户应用程序