JPQL을 사용하여 조인 테이블에서 항목을 삭제하려면 어떻게 해야 합니까?

StackOverflow https://stackoverflow.com/questions/1071940

  •  21-08-2019
  •  | 
  •  

문제

다음과 같은 다대다 관계를 갖는 JPA 객체가 있습니다.

@Entity
public class Role {
    //...

    @ManyToMany(fetch=FetchType.EAGER)
    @JoinTable(
    name="RolePrivilege",
    joinColumns=
        @JoinColumn(name="role", referencedColumnName="ID"),
    inverseJoinColumns=
        @JoinColumn(name="privilege", referencedColumnName="ID")
    )
    private Set<Privilege> privs;
}

RolePrivilege에 대한 JPA 개체가 없으므로 역할 개체의 privs 필드에서 항목을 삭제하기 위해 JPQL 쿼리를 작성하는 방법을 잘 모르겠습니다.예를 들어, 나는 이것을 시도했지만 작동하지 않습니다.Role.privs가 매핑되지 않았다고 불평합니다.

DELETE FROM Role.privs p WHERE p.id=:privId

그 밖에 무엇을 시도해야 할지 잘 모르겠습니다.물론 조인 테이블 RolePrivilege에서 삭제하는 기본 쿼리를 작성할 수도 있습니다.하지만 이렇게 하면 기본 쿼리로 업데이트되지 않는 로컬로 캐시된 개체와 잘못 상호 작용할 수 있다는 점이 걱정됩니다.

이와 같은 조인 테이블에서 항목을 제거하기 위해 JPQL을 작성하는 것이 가능합니까?그렇지 않다면 모든 Role 개체를 로드하고 각 개체의 privs 컬렉션에서 항목을 제거한 다음 각 역할을 유지할 수 있습니다.그러나 간단한 JPQL 쿼리로 모든 작업이 한꺼번에 수행된다면 그렇게 하는 것은 어리석은 것 같습니다.

도움이 되었습니까?

해결책

JPQL 업데이트 및 삭제 명령문은 테이블 이름이 아닌 엔티티 이름을 참조해야하므로 제안한 접근 방식에 운이 좋지 않다고 생각합니다.

JPA 제공 업체에 따라 간단한 원시 SQL 문 (100% 휴대용이어야 함)을 사용하여 조인트에서 항목을 삭제 한 다음 캐시 제공 업체 API와 프로그래밍 방식으로 상호 작용하여 데이터를 퇴거시킬 수 있습니다. 예를 들어 Hibernate에서는 evict ()에게 전화하여 2 단계 캐시에서 모든 "role.privs"컬렉션을 만료 할 수 있습니다.

sessionFactory.evictCollection("Role.privs", roleId); //evict a particular collection of privs
sessionFactory.evictCollection("Role.privs"); //evict all privs collections

불행히도 나는 JPA API와 함께 정확히 무엇이 지원되는지 확인하기에 충분히 일하지 않습니다.

다른 팁

또한 다대다 관계(조인 테이블에 포함됨)를 삭제하기 위한 JPQL 접근 방식을 찾고 있었습니다.분명히 ORM에는 테이블 개념이 없으므로 DELETE 작업을 사용할 수 없습니다.하지만 이런 경우에는 특별한 연산자가 있었으면 좋겠습니다.LINK 및 UNLINK와 같은 것입니다.어쩌면 미래의 기능일까요?

어쨌든, 이러한 요구를 충족하기 위해 제가 한 일은 다대다 관계를 매핑하는 엔터티 빈에 구현된 컬렉션을 사용하는 것이었습니다.

예를 들어, Courses와 다대다 관계를 갖는 Student 클래스가 있다면:

@ManyToMany
private Collection <Courses> collCourses;

해당 컬렉션에 대한 getter 및 setter를 엔터티에 구축합니다.그런 다음 예를 들어 EJB에서 getter를 사용하여 컬렉션을 검색하고 원하는 과정을 추가하거나 제거한 다음 마지막으로 setter를 사용하여 새 컬렉션을 할당합니다.그리고 끝났습니다.완벽하게 작동합니다.

그러나 나의 가장 큰 걱정은 성능입니다.ORM은 모든 객체의 거대한 캐시를 유지해야 하지만(제가 착각한 것이 아니라면) 이를 사용하여 더 빠르게 작업하더라도 컬렉션에서 모든 요소를 ​​검색하는 것이 정말 효과적인지 궁금합니다.

나에게는 내부 DB 엔진(SQL, JPQL...)과 직접 또는 간접적으로 작동하는 쿼리 언어 대신 테이블에서 레지스트리를 검색하고 순수 Java를 사용하여 사후 필터링하는 것만큼 비효율적이기 때문입니다.

Java는 객체 지향 언어이며 ORM의 요점은 조인 테이블의 세부 사항을 숨기는 것입니다. 결과적으로 결과를 고려하지 않고 조인 테이블에서 삭제를 고려하는 것은 이상 할 것입니다.

아니요 JPQL로는 할 수 없습니다.

어느 쪽 끝에서 엔티티를 검색하고 컬렉션을 지우십시오. 이렇게하면 조인 테이블 항목이 제거됩니다. 객체 지향.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top