我正在爲數據庫視圖的hibernate實體映射工作;當我對它進行標準查詢時,hibernate正在生成錯誤的SQL。任何幫助搞清楚我的映射的問題將不勝感激!錯誤的SQL使用Hibernate註解的視圖對象
我有兩個映射的實體,我試圖從數據庫視圖中獲取;該視圖沒有其他列,只是每個實體的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
@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 (?, ?...)
編輯我們項目的數據庫架構的具體細節時,我可能已經打亂了幾件事情,但重點是'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;
}
}
我會嘗試將它映射到主要,並標記爲答案,如果它的工作!感謝您的快速回復。你知道我在一般情況下如何處理這個問題,以與其他領域的觀點?另外,如何在添加新(最新)歷史記錄時確保該屬性在主對象上更新? – RMorrisey
不必更新屬性,因爲您不會維護它。你需要使用JoinTable來映射它:http://docs.jboss.org/hibernate/stable/annotations/reference/en/html/entity.html#d0e1177 就「視野與領域」而言,如果你需要爲了映射它,你需要將它映射爲實體。這意味着有一個**真正的**主鍵,而不是偶然發生的事情:-)您可以使用複合ID來映射包含多列的PK,但可能會產生難看的副作用。查看複合標識符的Hibernate文檔以獲取更多詳細信息。 – ChssPly76
這讓我可以消除n + 1選擇問題,並且可以大大加快批量處理速度,從而實現幾千種初選。謝謝=) – RMorrisey