문제

데이터베이스보기를 위해 최대 절전 모드 엔티티 매핑을 작업하고 있습니다. 기준 쿼리를 수행하면 최대 절전 모드가 잘못된 SQL을 생성합니다. 내 매핑에 문제가 무엇인지 파악하는 데 도움이 될 것입니다.

데이터베이스보기에서 잡으려고하는 두 개의 매핑 된 엔티티가 있습니다. 보기에는 다른 열이 없으며 각 엔티티의 FK 만 있습니다. 이 FK 중 하나는 각 기본 엔티티에 대한 행이 있기 때문에이 FK 중 하나는 기본 키로 취급 될 수 있습니다. 따라서보기 용 DB 스키마는 다음과 같습니다.

primary(primary_id, some_other_fields)
history(history_id, primary_id, some_other_fields)
view_latest_status_history(primary_id, history_id)

참고 뷰는 모든 매핑 된 기록 기록이 아니라 각 기본에 대한 최신 기록 만 선택하기 때문에 사용됩니다. Entity Annotations와 함께보기에 내가 사용하는 객체는 다음과 같습니다.

@Entity
@org.hibernate.annotations.Entity(dynamicUpdate = true)
@Table(name = "view_latest_status_history")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class ViewLatestStatusHistoryRow implements Serializable {
    private Primary primary;
    private History history;

    /**
     * @return Returns the history.
     */
    @ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, fetch = FetchType.LAZY)
    @JoinColumn(name = "history_id", nullable = true)
    @AccessType("field")
    public History getHistory() {
        return history;
    }

    //equals() and hashCode() implementations are omitted

    /**
     * @return Returns the primary.
     */
    @Id
    @ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, fetch = FetchType.LAZY)
    @JoinColumn(name = "primary_id", nullable = false)
    @AccessType("field")
    public Primary getPrimary() {
        return primary;
    }
}

기본 및 히스토리 객체 모두 완전한 작업 엔티티 주석이 있습니다.

내 기준 설정 :

criteria.add(Restrictions.in("primary", [collection of primary objects]));
criteria.setFetchMode("primary", FetchMode.JOIN);
criteria.setFetchMode("history", FetchMode.JOIN);

그리고 (잘못된) 생성 된 SQL :

select this_.primary as primary78_1_, this_.primary_id as prim2_78_1_, primary2_.history_id as unique1_56_0_, ...history fields
from DB_CATALOG.dbo.view_latest_status_history this_ 
left outer join DB_CATALOG.dbo.history primary2_ on this_.primary_id=primary2_.primary_id 
where this_.specChange in (?, ?...)

프로젝트의 DB 스키마의 세부 사항을 편집 할 때 몇 가지 사항을 만들었을 수도 있지만 요점은 'Select'절의 첫 번째 필드가 잘못되었습니다.

this_.primary (view_latest_status_history.primary)는 필드가 아닙니다. 필드를 Primary_ID라고해야합니다. 나는 이것이 기본 필드의 @id 주석과 관련이있을 수 있다고 생각합니까? 이것을 고치는 방법이 있습니까? @id를 제거하면 엔티티에 기본 키가 없다는 오류가 발생합니다.

업데이트:

더 이상 조인 테이블 표기법을 사용하여보기를 필드로 매핑하지 않습니다 (아래 제안 된대로). 주석은 다음과 같이 개정되었습니다. 이 솔루션은 HQL에서 올바르게 작동하며 HBM2DDL이 활성화 될 때 예상 스키마를 생성하지만 기준 쿼리를 사용하여 다시 테스트하지 않았습니다.

@Entity
@Table(name = "view_latest_status_history")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class ViewLatestStatusHistoryRow implements Serializable {
    private String id;
    private Primary primary;
    private History history;

    /**
     * @return Returns the history.
     */
    @OneToOne(optional = true)
    @JoinColumn(name = "history_id", nullable = true)
    @AccessType("field")
    public History getHistory() {
        return history;
    }

    //equals() and hashCode() implementations are omitted

    @Id
    @Column(name = "primary_id", nullable = false)
    @Override
    @AccessType(value = "field")
    public String getId() {
        return id;
    }

    /**
     * @return Returns the primary.
     */
    @PrimaryKeyJoinColumn(name = "primary_id", referencedColumnName = "unique_id")
    @OneToOne(optional = false)
    @AccessType("field")
    public Primary getPrimary() {
        return primary;
    }
}
도움이 되었습니까?

해결책

그것은 가장 확실하게 예정되어 있습니다 @Id 주석 -이 경우 기본 키는 기본 키가 아닙니다. 같은 속성에 현실적으로 @id 및 @manytoone을 가질 수 없습니다.

이걸 물어 보겠습니다 - 왜 매핑 하는가? ViewLatestStatusHistoryRow 시작할 실체로? 당신이 그것을 지속하려는 것과는 다릅니다. 기본 (다중 하나)에서 최신 기록 항목을 직접 (읽기 전용) 직접 매핑하고 뷰를 조인 테이블로 사용하는 것을 고려하십시오.

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