Ich bin mit Hibernate 5.1.2Hibernate Annotations @Where nicht mit Vererbung arbeiten
Ich habe in ein unerwartetes Problem führen, dass ich nicht um zu arbeiten scheinen. Hier ist die Zusammenfassung meiner Datenmodell:
dfip_project_version
ist mein Super Tisch und dfip_appln_proj_version
ist meine Unterklasse Tabelle. dfip_application
enthält eine Liste von dfip_appln_proj_version
s.
Ich habe dies wie folgt abgebildet:
@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 = [];
}
ich die @Where
Anmerkung verwende, so dass nur der aktuelle ApplicationProjectVersion
mit dem Application
abgerufen wird.
Das Problem dabei ist, dass Hibernate davon ausgeht, dass die Spalte, die ich referenziere, in der dfip_appl_proj_version
-Tabelle ist, wenn es tatsächlich in der Superklasse-Tabelle ist (dfip_project_version
).
Hier ist, was ich, um diese Einschränkung zu arbeiten bisher versucht:
Versuch 1
ich die @Where
Anmerkung auf die AbstractProjectVersion
Super-Klasse setzen versucht, etwa so:
@Table(name = "DFIP_PROJECT_VERSION")
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Where(clause = "PROJ_VSN_EFF_TO_DTM is null")
public abstract class AbstractProjectVersion {
...etc...
}
Dies hat nichts bewirkt, da die WHERE-Klausel beim Abrufen der Application
nicht bemerkt zu werden scheint.
Versuch 2
Ich habe die applicationVersions
Liste auf Application
LAZY und versuchte latestVersion
manuell wie folgt zuzuordnen:
@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;
}
Diese Hibernate verursacht die folgende SQL (Snippet zu generieren):
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
, die in ORA-01799: a column may not be outer-joined to a subquery
resultierte.
Wenn ich nicht eine Unterabfrage in meiner beitreten Formel angeben kann, dann kann ich nicht von Hand in der Super-Klasse beitreten ...
Versuch 3
Ich bemerkte, dass Verwendung von @JoinFormula
macht Hibernate bemerken meine @Where
Annotation auf der Super-Klasse. Also versuchte ich folgendes:
@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;
}
Dies erzeugt die folgende SQL (Snippet):
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
Diese fast richtig ist!Leider ist es nicht gültig SQL, da applicatio2_1_
verwendet wird, bevor es in der nächsten Zeile deklariert ist :(.
Jetzt habe ich aus Ideen bin, so würde jede mögliche Hilfe geschätzt. Gibt es eine Möglichkeit ein angeben WHERE-Klausel, die nur in der aktuellen ProjectVersion bringen wird, ohne meiner Vererbungsstruktur loszuwerden?
Related Hibernate issue ticket