我正在使用休眠5.1.2休眠@Where註解不與繼承工作
我遇到了意想不到的問題,我似乎無法解決。這是我的數據模型的總結:
dfip_project_version
是我的父表,dfip_appln_proj_version
是我的子類的表。 dfip_application
包含dfip_appln_proj_version
s的列表。
我制訂具體步驟如下:
@Table(name = "DFIP_PROJECT_VERSION")
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class AbstractProjectVersion {
@Id @GeneratedValue
@Column(name = "PROJECT_VERSION_OID")
Long oid;
@Column(name = "PROJ_VSN_EFF_FROM_DTM")
Timestamp effFromDtm;
@Column(name = "PROJ_VSN_EFF_TO_DTM")
Timestamp effToDtm;
@Column(name = "PROJECT_VERSION_TYPE")
@Type(type = "project_version_type")
ProjectVersionType projectVersionType;
}
@Table(name = "DFIP_APPLN_PROJ_VERSION")
@Entity
class ApplicationProjectVersion extends AbstractProjectVersion {
@OneToOne
@JoinColumn(name = "APPLICATION_OID", nullable = false)
Application application;
public ApplicationProjectVersion() {
projectVersionType = ProjectVersionType.APPLICATION;
}
}
@Table(name = "DFIP_APPLICATION")
@Entity
class Application {
@Id @GeneratedValue
@Column(name = "APPLICATION_OID")
Long oid;
@OneToMany(mappedBy="application", orphanRemoval = true, fetch = FetchType.EAGER)
@Fetch(FetchMode.SELECT)
@Where(clause = "PROJ_VSN_EFF_TO_DTM is null")
List<ApplicationProjectVersion> applicationVersions = [];
}
我使用@Where
註釋,這樣只有當前ApplicationProjectVersion
與Application
檢索。
問題在於,Hibernate假定我所引用的列在dfip_appl_proj_version
表中,當它實際位於超類表(dfip_project_version
)中時。
這裏是我試過至今解決此限制:
嘗試1
我試圖把@Where
註釋到AbstractProjectVersion
超一流的,像這樣:
@Table(name = "DFIP_PROJECT_VERSION")
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Where(clause = "PROJ_VSN_EFF_TO_DTM is null")
public abstract class AbstractProjectVersion {
...etc...
}
這沒有做什麼,因爲在檢索Application
時WHERE子句似乎沒有被注意到。
嘗試2
我發上Application
懶惰applicationVersions
列表中,並試圖手動映射latestVersion
這樣的:
@Table(name = "DFIP_APPLICATION")
@Entity
class Application {
@Id @GeneratedValue
@Column(name = "APPLICATION_OID")
Long oid;
@OneToMany(mappedBy="application", orphanRemoval = true, fetch = FetchType.LAZY)
@Fetch(FetchMode.SELECT)
List<ApplicationProjectVersion> applicationVersions = [];
@ManyToOne
@JoinColumnsOrFormulas([
@JoinColumnOrFormula(formula = @JoinFormula(value = "(APPLICATION_OID)", referencedColumnName="APPLICATION_OID")),
@JoinColumnOrFormula(formula = @JoinFormula(value = "(select apv.PROJECT_VERSION_OID from DFIP_PROJECT_VERSION pv, DFIP_APPLN_PROJ_VERSION apv where apv.PROJECT_VERSION_OID = pv.PROJECT_VERSION_OID and apv.APPLICATION_OID = APPLICATION_OID and pv.PROJ_VSN_EFF_TO_DTM is null)", referencedColumnName="PROJECT_VERSION_OID")),
])
ApplicationProjectVersion latestVersion;
}
這導致休眠生成以下SQL(片斷):
from DFIP_APPLICATION this_
left outer join DFIP_APPLN_PROJ_VERSION applicatio2_
on (this_.APPLICATION_OID)=applicatio2_.APPLICATION_OID and
(select apv.PROJECT_VERSION_OID from DFIP_PROJECT_VERSION pv, DFIP_APPLN_PROJ_VERSION apv
where apv.PROJECT_VERSION_OID = pv.PROJECT_VERSION_OID and apv.APPLICATION_OID = this_.APPLICATION_OID
and pv.PROJ_VSN_EFF_TO_DTM is null)=applicatio2_.PROJECT_VERSION_OID
其中產生ORA-01799: a column may not be outer-joined to a subquery
。
如果我不能指定我加入公式一個子查詢,那麼我不能加入手動超一流...
嘗試3
我注意到,使用@JoinFormula
會讓Hibernate在超級類別上注意我的@Where
註釋。所以,我試過如下:
@Table(name = "DFIP_PROJECT_VERSION")
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Where(clause = "PROJ_VSN_EFF_TO_DTM is null")
public abstract class AbstractProjectVersion {
...etc...
}
@Table(name = "DFIP_APPLICATION")
@Entity
class Application {
@Id @GeneratedValue
@Column(name = "APPLICATION_OID")
Long oid;
@OneToMany(mappedBy="application", orphanRemoval = true, fetch = FetchType.LAZY)
@Fetch(FetchMode.SELECT)
List<ApplicationProjectVersion> applicationVersions = [];
@ManyToOne
@JoinFormula(value = "(APPLICATION_OID)", referencedColumnName="APPLICATION_OID")
ApplicationProjectVersion latestVersion;
}
這產生了下面的SQL(片段):
from DFIP_APPLICATION this_
left outer join DFIP_APPLN_PROJ_VERSION applicatio2_
on (this_.APPLICATION_OID)=applicatio2_.APPLICATION_OID and (applicatio2_1_.PROJ_VSN_EFF_TO_DTM is null)
left outer join DFIP_PROJECT_VERSION applicatio2_1_ on applicatio2_.PROJECT_VERSION_OID=applicatio2_1_.PROJECT_VERSION_OID
這幾乎是正確的!不幸的是它不是有效的SQL,因爲applicatio2_1_
它在下一行:(聲明之前使用。
現在我的想法,所以任何幫助,將不勝感激。有沒有指定的方式WHERE子句將僅在當前ProjectVersion帶來的,沒有擺脫我的繼承結構的?
Related Hibernate issue ticket