从jsr-303自定义validation器访问数据库

我在我的应用程序上下文中使用基于弹簧的validation与hibernatevalidation器结合使用以下内容:

 ....        

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

 entityManager.setFlushMode(FlushModeType.COMMIT); 

这导致hibernate的“集合不通过flush()处理”exception。

是否有一个从自定义validation器访问数据库的最佳实践示例,这将允许我解决这两个问题?

经过多次实验,看起来最好的方法是直接在代码中使用EntityManagerFactory。 在validation器类的initialize(…)方法中,我有以下代码:

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

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

我也遇到了这个问题,这就是我解决它的方法: @Autowired bean在控制器上与@Valid一起工作但在CRUD存储库中失败

简而言之,我还获得了对EntityManagerFactory对象的引用。 但是,我在调用服务方法之前将setFlushMode设置为setFlushMode 。 最后我将它设置回FlushModeType.AUTO

这是一个例子:

 public class UniqueUsernameValidator implements ConstraintValidator { @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); } } }