gpt4 book ai didi

java - hibernate 唯一 key 验证

转载 作者:IT老高 更新时间:2023-10-28 13:51:48 24 4
gpt4 key购买 nike

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

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

最佳答案

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

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

关于java - hibernate 唯一 key 验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4613055/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com