Created
December 17, 2014 06:04
-
-
Save tag1216/18f1e521e8885d7e53f3 to your computer and use it in GitHub Desktop.
ユニーク制約チェック
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* ユニーク制約チェック | |
*/ | |
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