나는 Spring/JPA/Hibernate를 사용한다. 나는 꽤 표준적인 Dao와 Service 레이어 구현을 가지고있다.관련 엔티티의 ConstraintViolation 후에 분리 된 Hibernate 객체
class GenericDao<T> {
public save(T entity) {
if (!entity.isIdSet()) {
getEntityManager().persist(entity);
}
// other cases are update,
// so a transactional service method will suffice
// we dont need to do anything
}
}
class ParentEntity {
// Nothing special here, just an entity with auto-generated PK, if that matters
}
class RelatedEntity {
// Fairly standard many-to-one relation
@Column(name = "parent_id",nullable = false,insertable = false,updatable = false)
public Integer getParentId() {
return parentId;
}
@NotNull
@JoinColumn(name = "parent_id", nullable = false)
@ManyToOne(cascade = {PERSIST, MERGE}, fetch = LAZY)
public ParentEntity getParent() {
return parent;
}
}
class Repository<T> { // There is an implementation of this for both entities above
@Transactional
public void save(T entity) { getDao().save(entity); }
}
이제 문제, 나는 데 - 나는 데이터베이스에 여러 기록을 창조하는 RelatedEntity에 대한 데이터를 포함하는 파일을 읽고있다
. 그 동안 부모 참조를 설정해야합니다. 자식 레코드를 삽입 할 때마다 부모 엔티티를 조회하고 싶지 않습니다. 그래서 모든 부모 레코드 목록을 만들고 부모 엔티티의지도를 유지합니다 (이 세트는 10보다 작습니다). 데이터를 반복하고 자식에서 부모 참조를 설정하고 자식을 저장합니다.
public void getParentList {
List parentList = parentRepository.find();
// create a map with the list items for easy lookup on name
}
public void importData() {
for (line : file) {
RelatedEntity re = new RelatedEntity();
re.setParent(map.get(line.parentName)); // The refered object is got once in getParentList
// lookup the map for the parent
// set all properties of re here
childRepository.save(re);
}
}
지금까지 모두 양호합니다.
들어오는 데이터의 유효성을 확실하게 확인하지 않고 대신 엔터티에 이미 설정된 JPA 유효성 검사를 사용하려고합니다. 그래서 save()에 대한 제약 조건 voilation 예외를 처리하고 유효성을 검사하지 않는 레코드는 무시하고 싶습니다. 그러나 나머지 데이터를 계속 사용하려고합니다. 내가 그렇게 할 때
, 나는 예외를 얻을 :
javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.myads.domain.ParentEntity
public void importData() {
for (line : file) {
RelatedEntity re = new RelatedEntity();
// lookup the map for the parent
// set all properties of re here
try {
childRepository.save(re);
} catch (CVE cve) {
// log the record that failed validation
/*************
// Note: If I land here on line(x), I get PersistenceException on save for the
// next iteration(x+1).
**************/
}
}
}
그래서 부모 개체가 자식 엔티티가 지속성 예외를 throw 세션에서 분리되는 것 같습니다. 아이의 과목 동안 예외가 없다면, 모든 것이 잘 작동합니다.
그래서 무엇이 문제이며 해결책은 무엇입니까?
도움을 주시면 감사하겠습니다.
내 경우 예외는 Hibernate 유효성 검사기 인 pre-perist에 의해 예외가 발생했습니다. 따라서 JSR 303 유효성 검사가 최대 절전 모드가 유지되기 전에 시작되므로 정확히 SQL 예외는 아닙니다. 그렇지 않니? 이 경우 세션 상태가 전혀 영향을받지 않아야합니다. 빈에 대한 모든 제약 조건을 설정하는 것은 매우 논리적으로 들리지 않습니다. 예외에서 복구하고 계속하기를 원하기 때문에 만 유효성 검사기를 수동으로 호출하기 위해 bean 유효성 검사기를 사용하십시오. – Anupama
doc에 "including any SQLException"이 표시됩니다. "SQLExceptions를 제외한 모든 예외 제외"는 아닙니다. 엔티티에 대한 JSR-303 유효성 검사는 데이터베이스에서 현명한 제한 조건으로 간주되어야합니다. 그것들을 사용하여 데이터베이스에 정크가 포함되어 있지 않다는 것을 확인했지만, 마지막 수단으로 유효성 검사를 수행하기 때문에 이전에 데이터의 유효성을 검사 할 수 없으며 롤백해야합니다. 물론 문서가 말하는 것을 무시해도됩니다. 그러나 작동하지 않는다면 불평하지 마십시오. –