Java 从jsr-303自定义验证器访问数据库

Java 从jsr-303自定义验证器访问数据库,java,spring,validation,bean-validation,Java,Spring,Validation,Bean Validation,我将基于spring的验证与hibernate validator结合使用,在我的应用程序上下文中通过以下方式启用: <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> .... <property name="jpaPropertyMap"> <m

我将基于spring的验证与hibernate validator结合使用,在我的应用程序上下文中通过以下方式启用:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        ....
        <property name="jpaPropertyMap">
            <map>
                <entry key="javax.persistence.validation.factory" value-ref="validator" />    
            </map>
        </property>
    </bean>

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
这导致hibernate出现“collection not process by flush()”异常


是否有一个从自定义验证器中访问数据库的最佳实践示例,可以让我绕过这两个问题?

经过大量实验,似乎最好的方法是直接从代码中使用EntityManagerFactory。在验证器类的initialize(…)方法中,我有以下代码:

entityManager.setFlushMode(FlushModeType.COMMIT);
EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu_name");
entityManager = emf.createEntityManager(); 

缺点是您没有Spring的DI功能,但是您仍然可以访问数据库。

我也遇到了这个问题,下面是我如何解决它的:

简单地说,我还获得了对
EntityManagerFactory
对象的引用。但是,在调用我的服务方法之前,我将
setFlushMode
设置为
FlushModeType.COMMIT
。最后,我将其设置回FlushModeType.AUTO:

以下是一个例子:

public class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername, String> {

    @PersistenceContext
    private EntityManager em;

    @Autowired
    UserService userService;

    @Override
    public void initialize(UniqueUsername constraintAnnotation) {       
    }

    @Override
    public boolean isValid(String username, ConstraintValidatorContext context) {
        try { 
            em.setFlushMode(FlushModeType.COMMIT);          
            return userService.findByUsername(username) == null;

            } finally { 
           em.setFlushMode(FlushModeType.AUTO);
           }    
    }
}
公共类UniqueUsernameValidator实现ConstraintValidator{
@持久上下文
私人实体管理者;
@自动连线
用户服务用户服务;
@凌驾
public void initialize(UniqueUsername constraintanotation){
}
@凌驾
公共布尔值有效(字符串用户名、ConstraintValidatorContext上下文){
试试{
em.setFlushMode(FlushModeType.COMMIT);
返回userService.findByUsername(username)==null;
}最后{
em.setFlushMode(FlushModeType.AUTO);
}    
}
}
类似的问题:IMHP Spring的方法是将
@Autowired
服务或DAO类连接到验证器,并像往常一样使用它们。