【问题标题】:Database access from jsr-303 custom validator从 jsr-303 自定义验证器访问数据库
【发布时间】:2011-09-29 12:51:53
【问题描述】:

我在我的应用程序上下文中将基于弹簧的验证与通过以下启用的休眠验证器结合使用:

<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"/>

我已经实现了一个自定义验证器,它访问数据库以使用 spring 注入的 DAO 检查特定对象的有效性约束。这会导致 java.lang.StackOverflowError,因为每次从验证器中从数据库加载对象时都会调用验证,从而导致无限循环。为了解决这个问题,我尝试在我的实体管理器上设置刷新模式,以使用以下代码从验证器中提交:

entityManager.setFlushMode(FlushModeType.COMMIT);

这会导致 hibernate 的“collection not process by flush()”异常。

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

【问题讨论】:

标签: java spring validation bean-validation


【解决方案1】:

我也遇到过这个问题,解决方法如下: @Autowired bean works with @Valid on controller but fails with CRUD repository

简而言之,我还得到了对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);
           }    
    }
}

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      • 2015-03-28
      • 1970-01-01
      • 1970-01-01
      • 2011-08-09
      • 2013-05-27
      • 2019-02-03
      相关资源
      最近更新 更多