최대 절전 모드 주석을 사용하여보기 객체에 대한 잘못된 SQL
-
10-07-2019 - |
문제
데이터베이스보기를 위해 최대 절전 모드 엔티티 매핑을 작업하고 있습니다. 기준 쿼리를 수행하면 최대 절전 모드가 잘못된 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
시작할 실체로? 당신이 그것을 지속하려는 것과는 다릅니다. 기본 (다중 하나)에서 최신 기록 항목을 직접 (읽기 전용) 직접 매핑하고 뷰를 조인 테이블로 사용하는 것을 고려하십시오.