Skip to content

Instantly share code, notes, and snippets.

@tag1216
Created December 17, 2014 06:04
Show Gist options
  • Save tag1216/18f1e521e8885d7e53f3 to your computer and use it in GitHub Desktop.
Save tag1216/18f1e521e8885d7e53f3 to your computer and use it in GitHub Desktop.
ユニーク制約チェック
@Documented
@Constraint(validatedBy = UniqueValidator.class)
@Target({ ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Unique {
String message() default "dv3j.core.validation.Unique.message";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
Class<?> entity();
String[] property();
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface List {
Unique[] value();
}
}
/**
* ユニーク制約チェック
*/
public class UniqueValidator implements ConstraintValidator<Unique, Object> {
private Unique constraint;
private Class<?> entityClass;
private String[] columnNames;
@PersistenceContext(unitName = "default")
private EntityManager entityManager;
public UniqueValidator() {
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
public void initialize(Unique constraint) {
this.constraint = constraint;
entityClass = constraint.entity();
columnNames = constraint.property();
}
@Override
public boolean isValid(Object target, ConstraintValidatorContext context) {
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);
Object propertyValue = BeanUtils.getProperty(target, propertyName);
Predicate predicate = criteriaBuilder.equal(root.get(propertyName), propertyValue);
predicates.add(predicate);
}
Field idField = getIdField(entityClass);
String idProperty = idField.getName();
Object idValue = getPropertyValue(target, idProperty);
if (idValue != null) {
Predicate idNotEqualsPredicate = criteriaBuilder.notEqual(root.get(idProperty), idValue);
predicates.add(idNotEqualsPredicate);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
criteriaQuery.select(root).where(predicates.toArray(new Predicate[predicates.size()]));
TypedQuery<Object> typedQuery = entityManager.createQuery(criteriaQuery).setFlushMode(FlushModeType.COMMIT);
List<Object> resultSet = typedQuery.getResultList();
if (!resultSet.isEmpty()) {
// This string will contain all column names separated by a comma. Example: "title,author,editor"
String names = columnNames[columnNames.length-1];
ConstraintViolationBuilder cvb = context.buildConstraintViolationWithTemplate(constraint.message());
NodeBuilderCustomizableContext nbdc = cvb.addPropertyNode(names);
ConstraintValidatorContext cvc = nbdc.addConstraintViolation();
cvc.disableDefaultConstraintViolation();
return false;
}
return true;
}
private Field getIdField(Class<?> entityClass) {
return ReflectionUtils.findField(entityClass, "id");
}
private Object getPropertyValue(Object target, String propertyName) {
ConfigurablePropertyAccessor accessor = PropertyAccessorFactory.forBeanPropertyAccess(target);
return accessor.getPropertyValue(propertyName);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment