hibernate独特的密钥验证 [英] hibernate unique key validation

查看:106
本文介绍了hibernate独特的密钥验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



什么是使用Spring / Hibernate验证验证它的最好方法是什么?

解决方案

可能的解决方案之一是创建自定义 @UniqueKey 约束(和相应的验证器);并查找数据库中的现有记录,将 EntityManager (或Hibernate Session )的实例提供给 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;

尝试{
instance = key.newInstance();
} catch(Exception e){
//无法实例化类
e.printStackTrace(); (EntityManagerAwareValidator.class.isAssignableFrom(key)){
EntityManagerAwareValidator validator =(EntityManagerAwareValidator)实例;
}

if
validator.setEntityManager(entityManagerFactory.createEntityManager());
}

返回实例;




UniqueKey

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

String [] columnNames();

字符串消息()默认{UniqueKey.message};

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

类<?扩展了Payload> [] payload()default {};

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




UniqueKeyValidator

  public class UniqueKeyValidator实现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);

列表<谓词> predicates = new ArrayList< Predicate> (columnNames.length);

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

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

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

列表< Object> resultSet = typedQuery.getResultList();

返回resultSet.size()== 0;
}

}

用法

  @UniqueKey(columnNames = {userName})
// @UniqueKey(columnNames = {userName ,emailId})//复合唯一键
//@UniqueKey.List(value = {@UniqueKey(columnNames = {userName}),@UniqueKey(columnNames = {emailId})} )//多个唯一键
public class User实现Serializable {

private String userName;
私人字符串密码;
private String emailId;

保护用户(){
super();
}

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

Test

  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 =新用户(abc,poizon);

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

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

用户se1 =新用户(abc);

violation = validator.validate(se1);

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


I have a field, say, user_name, that should be unique in a table.

What is the best way for validating it using Spring/Hibernate validation?

解决方案

One of the possible solutions is to create custom @UniqueKey constraint (and corresponding validator); and to look-up the existing records in database, provide an instance of EntityManager (or 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;
    }
}

UniqueKey

@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;
    }

}

Usage

@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;
    }
        ....
}

Test

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());
}

这篇关于hibernate独特的密钥验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆