当前位置: 首页 > 面试题库 >

休眠唯一密钥验证

墨承泽
2023-03-14
问题内容

我有一个字段,例如,user_name在表中应该是唯一的。

使用Spring / Hibernate验证进行验证的最佳方法是什么?


问题答案:

一种可能的解决方案是创建自定义@UniqueKey约束(和相应的验证器)。并在数据库中查找现有记录,请提供EntityManager(或Hibernate
Session)to 的实例UniqueKeyValidator

EntityManagerAwareValidator

public interface EntityManagerAwareValidator {  
     void setEntityManager(EntityManager entityManager); 
}

ConstraintValidatorFactoryImpl

public class ConstraintValidatorFactoryImpl implements ConstraintValidatorFactory {

    private EntityManagerFactory entityManagerFactory;

    public ConstraintValidatorFactoryImpl(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }

    @Override
    public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
        T instance = null;

        try {
            instance = key.newInstance();
        } catch (Exception e) { 
            // could not instantiate class
            e.printStackTrace();
        }

        if(EntityManagerAwareValidator.class.isAssignableFrom(key)) {
            EntityManagerAwareValidator validator = (EntityManagerAwareValidator) instance;
            validator.setEntityManager(entityManagerFactory.createEntityManager());
        }

        return instance;
    }
}

唯一键

@Constraint(validatedBy={UniqueKeyValidator.class})
@Target({ElementType.TYPE})
@Retention(RUNTIME)
public @interface UniqueKey {

    String[] columnNames();

    String message() default "{UniqueKey.message}";

    Class<?>[] groups() default {};

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

    @Target({ ElementType.TYPE })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        UniqueKey[] value();
    }
}

UniqueKeyValidator

public class UniqueKeyValidator implements ConstraintValidator<UniqueKey, Serializable>, EntityManagerAwareValidator {

    private EntityManager entityManager;

    @Override
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    private String[] columnNames;

    @Override
    public void initialize(UniqueKey constraintAnnotation) {
        this.columnNames = constraintAnnotation.columnNames();

    }

    @Override
    public boolean isValid(Serializable target, ConstraintValidatorContext context) {
        Class<?> entityClass = target.getClass();

        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

        CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();

        Root<?> root = criteriaQuery.from(entityClass);

        List<Predicate> predicates = new ArrayList<Predicate> (columnNames.length);

        try {
            for(int i=0; i<columnNames.length; i++) {
                String propertyName = columnNames[i];
                PropertyDescriptor desc = new PropertyDescriptor(propertyName, entityClass);
                Method readMethod = desc.getReadMethod();
                Object propertyValue = readMethod.invoke(target);
                Predicate predicate = criteriaBuilder.equal(root.get(propertyName), propertyValue);
                predicates.add(predicate);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));

        TypedQuery<Object> typedQuery = entityManager.createQuery(criteriaQuery);

        List<Object> resultSet = typedQuery.getResultList();

        return resultSet.size() == 0;
    }

}

用法

@UniqueKey(columnNames={"userName"})
// @UniqueKey(columnNames={"userName", "emailId"}) // composite unique key
//@UniqueKey.List(value = {@UniqueKey(columnNames = { "userName" }), @UniqueKey(columnNames = { "emailId" })}) // more than one unique keys
public class User implements Serializable {

    private String userName;
    private String password;
    private String emailId;

    protected User() {
        super();
    }

    public User(String userName) {
        this.userName = userName;
    }
        ....
}

测试

public void uniqueKey() {
    EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("default");

    ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
    ValidatorContext validatorContext = validatorFactory.usingContext();
    validatorContext.constraintValidatorFactory(new ConstraintValidatorFactoryImpl(entityManagerFactory));
    Validator validator = validatorContext.getValidator();

    EntityManager em = entityManagerFactory.createEntityManager();

    User se = new User("abc", poizon);

       Set<ConstraintViolation<User>> violations = validator.validate(se);
    System.out.println("Size:- " + violations.size());

    em.getTransaction().begin();
    em.persist(se);
    em.getTransaction().commit();

        User se1 = new User("abc");

    violations = validator.validate(se1);

    System.out.println("Size:- " + violations.size());
}


 类似资料:
  • 问题内容: 我无法描述我的问题,请通过示例再次尝试: 我有两个实体(表): Department 和 Person 。这两个表有一个字段 CODE 这是 不是唯一的 。 如何 定义 这些表之间的manyToMany 双向关系 ? 部门人员具有收集人员,该人员返回具有Person.CODE eq Department.CODE的所有实体 合作伙伴有收集部门,该部门返回所有带有Department.C

  • 问题内容: 我有一个字段,例如,在表中应该是唯一的。 使用Spring / Hibernate验证进行验证的最佳方法是什么? 问题答案: 一种可能的解决方案是创建自定义约束(和相应的验证器)。并要查找数据库中的现有记录,请提供(或Hibernate)to 的实例。 EntityManagerAwareValidator ConstraintValidatorFactoryImpl 唯一键 Uniq

  • 问题内容: 我对hibernate.hbm2ddl.auto = validate的实际工作方式很感兴趣,并且正在努力寻找全面的文档。 我们最近发现生产系统受到http://opensource.atlassian.com/projects/hibernate/browse/HHH-3532的影响(hibernate匹配名称上的外键,而不是签名,因此将为您重新创建外键)并hibernate.hbm

  • 问题内容: 以下问题与我之前问过的一个问题有关:帮助解析简单的JSON(将JSON用于JAVA ME) JSON密钥需要唯一吗?例如,我在解析以下XML(使用JSON ME)时遇到了麻烦: 并且,显然是因为密钥必须唯一。我只是想知道在所有情况下是否都是这样。例如,如果我使用的不是JSON ME,我是否可以解析所有这些名称? 谢谢。 问题答案: 如果你使用多个具有相同名称的密钥,则不会出现“错误”,

  • 问题内容: 从Weblogic 11c切换到Weblogic 12c后,出现此异常: 我发现了有关该主题的其他问题,但是所有解决方案都是关于错误的库的(Vaadin 7-Bean Validation )。我认为我的hibernate-validator与bean验证器库匹配。这是我在WEB-INF / lib中拥有的: 可能是由其他依赖性引起的吗? 编辑 我目前在我的weblogic-appli

  • 问题内容: 我有一个hibernate映射,该映射一直工作到最近-尽管我确定这是我所做的某些更改的结果,但我似乎找不到它。 映射文件将字段定义为: 该类将该字段定义为: 运行此代码时,出现以下错误: 与此对应的数据库字段定义为: 我还有其他几个具有相似结构和定义的类,并且它们没有问题。但是,可能由于我最近所做的一些更改而导致,此特定映射将不再正常工作。 有什么建议么? 问题答案: 我不确定,但是您