source

테이블은 'UPDATE'의 타깃으로, 그리고 데이터의 개별 소스로서 두 번 지정됩니다.

lovecheck 2022. 12. 28. 21:42
반응형

테이블은 'UPDATE'의 타깃으로, 그리고 데이터의 개별 소스로서 두 번 지정됩니다.

하이버네이트 구현에는 spring-jpa를 사용합니다.mariadb를 사용하여 서브쿼리를 업데이트하려고 합니다.

내 객체 구조

@Entity
public class Room {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long roomId;

  @ManyToOne  
  @JoinColumn(name = "appartment_id")
  private Appartment appartment;
}

@Entity
public class Appartment {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long appartmentId;

  @OneToMany
  @JoinColumn(name="appartment_id")
  private Set<Room> roomList;
}

update Room r1
set r1.available = :availability
where r1.roomId in
( select r2.roomId from Room r2 JOIN r2.appartment a1 WHERE a1.appartmentId = :appartmentId )

이 에러가 표시된다.

java.sql.SQLException:테이블 'room'은 'UPDATE'의 타깃으로, 데이터 소스로서 각각 2회 지정됩니다.

이것은 MySQL의 제한 사항입니다.-

http://dev.mysql.com/doc/refman/5.7/en/update.html

테이블을 업데이트하고 하위 쿼리의 동일한 테이블에서 선택할 수 없습니다.

동작할 수 있는 하위 쿼리의 추가 수준에서 하위 쿼리를 숨기기 위해 가끔 수행할 수 있는 조작이 있습니다.이와 같은 것(테스트되지 않음):-

UPDATE Room r1
SET r1.available = :availability
WHERE r1.roomId IN
    SELECT roomId
    FROM
    ( 
        SELECT r2.roomId 
        FROM Room r2 
        JOIN r2.appartment a1 
        WHERE a1.appartmentId = :appartmentId 
    )

쿼리에 오류가 있을 수 있습니다.서브쿼리에서는 Room 에일리어스가 r2인 테이블을 데이터베이스상의 application이라는 테이블에 결합합니다.또한 서브쿼리는 조인 조건 없이 JOIN을 수행합니다.

단, 서브쿼리 없이 UPDATE 스테이트먼트에 가입만 할 수 있습니다.

UPDATE Room 
INNER JOIN r2.appartment a1
ON Room.roomId = a1.roomId
SET r1.available = :availability
WHERE a1.appartmentId = :appartmentId 

해결책은 다음과 같습니다.roomIds개별적으로 전달하고 매개 변수로 전달합니다.

ID 리스트 선택

List<Long> roomIdList = entityManager.createQuery(
                    """SELECT r2.roomId 
                    FROM Room r2 
                    JOIN r2.appartment a1 
                    WHERE a1.appartmentId = :appartmentId""", Long.class)
                    .setParameter("appartmentId", appartmentId)
                    .getResultList();

매개 변수로 전달

int updated = entityManager.createQuery(
                    """UPDATE Room r1
                    SET r1.available = :availability
                    WHERE r1.roomId IN :roomIds""")
                    .setParameter("availability", availability)
                    .setParameter("roomIds", roomIdList)
                    .executeUpdate();

언급URL : https://stackoverflow.com/questions/35486177/table-is-specified-twice-both-as-a-target-for-update-and-as-a-separate-source

반응형