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

Hibernate唯一密钥验证

佟阳焱
2023-03-14
问题内容

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

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


问题答案:

一种可能的解决方案是创建自定义@UniqueKey约束(和相应的验证器)。并要查找数据库中的现有记录,请提供EntityManager(或HibernateSession)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());
}


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

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

  • 问题内容: 我有一个实体类的两个字段,我不希望它们是唯一的,而是用作本身必须是唯一的键的复合字段。例如,我有两个字段(名称和版本),这些字段对于其他记录可以相同,但它们必须唯一。使用Hibernate(带有注释)做到这一点的最佳方法是什么?我正在将Hibernate Validator用于其他字段,但不确定如何使用该方法来验证两个字段一起组成唯一键。我正在使用具有id泛型类型的泛型实体类,可以将其

  • 我想使用自定义寄存器模型注册用户,但我一直收到以下错误: 重复的键值违反了唯一约束“auth_user_username_key”详细信息:键(username)=(无)已存在 我如何修复这个错误。 这是我到目前为止创建的代码: 在 urls.py 我为各个页面创建URL配置。 形式。py我创建自定义注册表单。 views.py我创建了寄存器视图函数。

  • 我正在使用JPA 如果我有一堆相关的实体,如下所示: 祖父母实体有许多父实体(一个实体)。使用联接表持久化 父实体有一个子实体(OneToOne)。在父表中使用child\u uuid持久化 如果我只获得了子唯一密钥,我如何获得祖父母实体? 我的想法是一个有3个连接的查询-子连接到父连接,父连接到表,将表连接到祖父母。这是最好的方式吗?

  • 我想为dynamodb中的订单创建一个表,每个订单由(UserID、date、Unique ID、products和total)组成,我想使用按日期排序的UserID查询特定用户的订单,我想知道如何选择分区键?它必须是独一无二的吗?如果是,我如何才能使它独一无二?在mongodb中,我会根据用户ID共享订单。如何使用dynamodb实现同样的效果?