현재 JPA를 사용하지만 JPA EnitytManager
(및 트랜잭션)이 DAO 계층으로 범위가 지정된 응용 프로그램을 현재 리팩토링하고 있습니다. 저장소 계층과 서비스 계층도 있습니다. 서비스 계층을 트랜잭션으로 만들고 서비스 계층에 대한 요청 당 하나의 EntityManger
을 갖고 싶습니다. 이상적으로 JPA에 대한 내 서비스 또는 저장소 계층에 대해 알 필요가 없습니다.JPA 모델 유효성 검사 및 트랜잭션 처리
현재 리포지토리와 서비스 계층은 DAO 계층에서 분리 된 엔터티와 함께 작동합니다. 모델이 변경되고 엔터티가 DAO 레이어로 병합됩니다. 새로운 구조에서 엔터티는 전체 요청 동안 관리 상태를 유지하며 1 요청은 1 트랜잭션 내에 포함됩니다. 변경 사항은 트랜잭션이 끝날 때 자동으로 커밋됩니다. 이것은 JPA의 정신에서 훨씬 더 많이 보이고 가장 일반적인 경우에 잘 작동합니다.
경우에 따라 모델이 변경되고 모델이 유효성을 검사하지만 때로는 유효성이 검사됩니다. 모델이 더 이상 유효하지 않으면 변경 사항이 저장되지 않아야합니다. 이전 구조에서는 이것은 간단했습니다 :
이 예제 프로세스에서는 기본적으로 그래프이며 전체 그래프는 유효성을 검사하고 자체 참조가 필요하지 않으며 모든 노드에 도달 할 수 있어야하며 첫 번째 노드에는 몇 가지 특별한 요구 사항이 있습니다. 최종 노드가 될지 등등. 우리는 먼저 모델을 변경 한 다음 모델을 검증합니다. 오래된
저장소 계층 코드 : 내가 생각하는 새로운 구조에서
changeProcessModel();
messages = ProcessValidator.validate(process);
if (messages.hasNoErrors()) {
processDao.merge(process);
messages.addInfoMessage("Process was updated succesfully");
}
return messages;
나는 세 가지 옵션이 내가 가장 좋은 방법으로 간주됩니다 하나의 질문을 해요, 또는 다른 대안이 있는지.
새로운 코드 옵션 1 :
changeProcessModel();
messages = ProcessValidator.validate(process);
if (messages.hasNoErrors()) {
messages.addInfoMessage("Process was updated succesfully");
} else {
throw new InvalidProcessException(messages);
}
return messages;
남용이 코드 정렬 일부 비즈니스 규칙의 검증을위한 RuntimeException
. 나는 이것이 베스트 프랙티스로 여겨지지 않는다고 생각하지만 트랜잭션은 롤백된다. 이것은 또한 엔티티가 유효성을 검사하지 않으면 예외를 throw하는 Bean Validation과 호환됩니다.
새로운 코드 옵션 2 :
changeProcessModel();
messages = ProcessValidator.validate(process);
if (messages.hasNoErrors()) {
messages.addInfoMessage("Process was updated succesfully");
} else {
em.getTransactionManager.rollback();
}
return messages;
이 코드는 JPA TransactionManager
에 직접 롤백을 수행하고 내 저장소 계층과 JPA 사이의 종속성을 소개합니다.
새로운 코드 옵션 3 :
changeProcessModel();
messages = ProcessValidator.validate(process);
if (messages.hasNoErrors()) {
messages.addInfoMessage("Process was updated succesfully");
} else {
processDao.refresh(process);
}
return messages;
이 코드는 꽤 좋은 것 같다,하지만이 CascadeType.REFRESH
에 의존 않습니다 제대로 새로 고칠 필요가있는 공정 엔티티 관계를 설정합니다.
또한 예를 들어 processDao.clear();
또는 processDao.rollback();
일 수 있습니다. 그러나 processDao
의 범위가 전체 entityManger
으로 증가 할 수 있습니다. 아주 깨끗한 방법인지 확실하지 않습니다.
이 점에 대해 어떻게 생각하십니까?