2016-05-27 17 views
0

Ich habe seit ein paar Tagen mit einer namedquery gekämpft. Die benannte Abfrage hat eine innere Verknüpfung mit einer zweiten Tabelle. Eine zusätzliche Komplexität besteht darin, dass der Primärschlüssel in der zweiten Tabelle ein zusammengesetzter Schlüssel ist. Ich habe die beiden Tabellen hier vereinfacht:JPA NamedQuery mit Beitreten, leere Liste zurückgeben

Table: aname 
nameIdx number(9), 
firstName varchar2(40), 
lastName varchar2(40), 

Primärschlüssel ist nameIdx

Table: aname_role 
nameIdx number(9), --foreign key to name table 
nameType char(2), 
inactiveFlag char(1) 

Verbundprimärschlüssel ist auf nameIdx und nametype

Ich versuche, die folgende SQL-Abfrage in JPQL zu emulieren:

select * from aname n 
    left join aname_role nr on n.nameidx=nr.nameidx 
where nr.nametype='5' 
    and nr.inactiveflag='N'; 

Diese Abfrage funktioniert wie erwartet in Oracle viele Datensätze zurückgeben. In Java habe ich diese JPA-Entitäten:

@Entity 
@Table(name="ANAME") 
@NamedQueries({ 
    @NamedQuery(name = "AName.findActiveSalesPersons", query = "SELECT a FROM AName a LEFT JOIN a.aNameRoleList r WHERE r.inactiveflag='N' and r.ANameRolePK.nametype='5' ")}) 
public class AName implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @Basic(optional = false) 
    @NotNull 
    @Column(name = "NAMEIDX") 
    private Integer nameidx; 
    @Column(name = "FIRSTNAME") 
    private String firstname; 
    @Column(name = "LASTNAME") 
    private String lastname; 
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "aName") 
    private List<ANameRole> aNameRoleList; 
    //getters and setters here 

und

@Entity 
@Table(name = "ANAME_ROLE") 
public class ANameRole implements Serializable { 

    private static final long serialVersionUID = 1L; 
    @EmbeddedId 
    protected ANameRolePK aNameRolePK; 
    @Basic(optional = false) 
    @NotNull 
    @Column(name = "INACTIVEFLAG") 
    private Character inactiveflag; 
    @JoinColumn(name = "NAMEIDX", referencedColumnName = "NAMEIDX", insertable = false, updatable = false) 
    @ManyToOne(optional = false) 
    private AName aName; 
    //getters and setters here 

Es gibt auch eine Primärschlüsselklasse ANameRolePK

@Embeddable 
public class ANameRolePK implements Serializable { 

    @Basic(optional = false) 
    @NotNull 
    @Column(name = "NAMEIDX") 
    private int nameidx; 
    @Basic(optional = false) 
    @NotNull 
    @Size(min = 1, max = 2) 
    @Column(name = "NAMETYPE") 
    private String nametype; 
    //getters and setters here 

Mit diesem Setup, einschließlich der benannten Abfrage in dem AName angegeben Über die folgende Entität wird eine leere Ergebnisliste zurückgegeben:

em.createNamedQuery("AName.findActiveSalesPersons").getResultList(); 

Kann mir jemand zeigen, was ich falsch in dieser named Abfrage mache?

SELECT a FROM AName a LEFT JOIN a.aNameRoleList r WHERE r.inactiveflag='N' and r.aNameRolePK.nametype='5' 

Danke,

Steve

Antwort

0

Nach mehr Tests, ich die Verbindung realisiert arbeitet, aber nicht die "r.aNameRolePK.nametype = '5'". Aber wenn ich das in "r.aNameRolePK.nameidx = 1" geändert habe, funktioniert es. Also, es war nur das NameType-Feld, das wir als char (2) in der Datenbank definiert haben. Das Problem ist mit den Leerzeichen in einem Zeichenfeld und es wird hier diskutiert: Java NamedQuery String Problem. Es sieht so aus, als ob die empfohlene Lösung zur Implementierung ein EclipseLink SessionCustomizer ist. Zum Testen habe ich die benannte Abfrage geändert in

SELECT a 
FROM AName a LEFT JOIN a.aNameRoleList r 
WHERE r.inactiveflag='N' and trim(trailing from r.aNameRolePK.nametype)=5 

Dies gibt die erwarteten Datensätze zurück.

0

standardmäßig mindestens Hibernate, holt der Standardtyp Lazy ist, so dass Sie ein join fetch anstelle ein join tun müssen. Außerdem sollten Sie select distinct haben. Versuchen:

SELECT distinct a FROM AName a LEFT JOIN fetch a.aNameRoleList r WHERE r.inactiveflag='N' and r.aNameRolePK.nametype='5' 

Referenzen: Default fetch type for one-to-one, many-to-one and one-to-many in Hibernate

+0

Dank Nicholas. Ich schaute auf holen. Wenn ich die Abfrage (nur um zu sehen, ob der Join funktioniert) zu "SELECT a FROM AName a LINKER JOIN a.aNameRoleList r WHERE r.inactiveflag = 'N'" (kein Abruf), gibt es Datensätze zurück. Es scheint, dass ich den Abruf zumindest nicht mit EclipseLink brauche. Ich weiß es zu schätzen, dass Sie sich den Code angeschaut haben. Es gab mir mehr Vertrauen in die genannte Abfrage und so probierte ich einige andere Dinge aus, die ich in eine separate Antwort einfügen werde. – Steve