栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在Hibernate验证期间执行EntityManager查询的正确方法

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在Hibernate验证期间执行EntityManager查询的正确方法

通过一些评论和足够的探讨,我终于找到了某种“规范”的方式来回答我的问题。

但是要弄清楚,我的问题确实是在问两件事,它们有两个不同的答案:

  1. 您如何将事物注入到Hibernate Validation框架中使用的Validator中?
  2. 假设我们可以注入事物,那么在JPA生命周期事件中注入EntityManagerFactory或EntityManager并将其用于查询是否安全?

首先我要简单回答第二个问题,强烈建议在验证过程中使用第二个EntityManager进行查询。这意味着您应该注入一个EntityManagerFactory并为查询创建一个新的EntityManager(而不是注入一个与创建生命周期事件的实体相同的EntityManager)。

一般来说,出于验证目的,您无论如何都只会查询数据库,而不会插入/更新,因此这样做相当安全。

现在回答问题1。

是的,完全有可能将事物注入到Hibernatevalidation框架中使用的Validator中。为此,您需要做三件事:

  1. 创建一个自定义ConstraintValidatorFactory,它将创建框架中使用的验证器(覆盖Hibernate的默认工厂)。(我的示例使用JavaEE,而不是Spring,所以我使用BeanManager,但在Spring中,您可能会为此使用ApplicationContext。)
  2. 创建一个validate.xml文件,该文件告诉Hibernatevalidation框架将哪个类用于ConstraintValidatorFactory。确保此文件最终出现在您的类路径中。
  3. 编写一个注入器的验证器。

这是使用“托管”(可注入)验证器的示例自定义ConstraintValidatorFactory:

package com.myvalidator;public class ConstraintInjectablevalidatorFactory implements ConstraintValidatorFactory {    private static BeanManager beanManager;    @SuppressWarnings(value="unchecked")    @Override    public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> clazz) {        // lazily initialize the beanManager        if (beanManager == null) { try {     beanManager = (BeanManager) InitialContext.doLookup("java:comp/BeanManager"); } catch (NamingException e) {     // TODO what's the best way to handle this?     throw new RuntimeException(e); }        }        T result = null;        Bean<T> bean = (Bean<T>) beanManager.resolve(beanManager.getBeans(clazz));        // if the bean/validator specified by clazz is not null that means it has        // injection points so get it from the beanManager and return it. The validator        // that comes from the beanManager will already be injected.        if (bean != null) { CreationalContext<T> context = beanManager.createCreationalContext(bean); if (context != null) {     result = (T) beanManager.getReference(bean, clazz, context); }        // the bean/validator was not in the beanManager meaning it has no injection        // points so go ahead and just instantiate a new instance and return it        } else { try {     result = clazz.newInstance(); } catch (Throwable t) {     throw new RuntimeException(t); }        }        return result;    }}

这是一个示例validation.xml文件,该文件告诉Hibernate Validator哪个类用作ValidatorFactory:

<?xml version="1.0" encoding="UTF-8"?><validation-config    xmlns="http://jboss.org/xml/ns/javax/validation/configuration"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.0.xsd">    <constraint-validator-factory>        com.myvalidator.ConstraintInjectablevalidatorFactory    </constraint-validator-factory></validation-config>

最后是带有注入点的验证器类:

public class UserValidator implements ConstraintValidator<ValidUser, User> {    @PersistenceUnit(unitName="myvalidator")    private EntityManagerFactory entityManagerFactory;    private EntityManager entityManager;    @Override    public void initialize(ValidUser annotation) {    }    @Override    public boolean isValid(User user, ConstraintValidatorContext context) {        // validation takes place during the entityManager.persist() lifecycle, so        // here we create a new entityManager separate from the original one that        // invoked this validation        entityManager = entityManagerFactory.createEntityManager();        // use entityManager to query database for needed validation        entityManager.close();    }}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/393185.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号