2016-05-27 30 views
0

我一直在爲查詢工作掙扎幾天。指定的查詢具有到第二個表的內部聯接。另一個增加的複雜性是第二個表上的主鍵是一個複合鍵。我在這裏簡單的兩個表:帶返回空列表的JPA NamedQuery

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

主鍵是nameIdx

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

複合主鍵是nameIdx和NAMETYPE

我試圖仿效JPQL下面的SQL查詢:

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

此查詢在Oracle返回許多記錄時按預期工作。在Java中我有這些JPA實體:

@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 

@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 

還有一個主鍵類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 

有了這個設置,包括AName指定的命名查詢以上實體,以下返回空結果列表:

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

任何人都可以指出我在這個命名查詢中做錯了什麼?

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

感謝,

史蒂夫

回答

0

更多的測試後,我才意識到是一起工作,但不是 「r.aNameRolePK.nametype = '5'」。但如果我將其改爲「r.aNameRolePK.nameidx = 1」,它就可以工作。所以,它只是nametype字段,我們在數據庫中將其定義爲char(2)。問題在於char字段中的空格,這裏討論它:Java NamedQuery String Problem。看起來解決此問題的建議方法是實施EclipseLink SessionCustomizer。對於測試,我將指定查詢更改爲

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

這將返回預期記錄。

0

默認情況下,至少使用Hibernate,默認提取類型爲Lazy,所以你需要做join fetch而不是join。此外,你應該有select distinct。嘗試:

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

參考文獻:Default fetch type for one-to-one, many-to-one and one-to-many in Hibernate

+0

謝謝尼古拉斯。我正在看取。如果我簡化查詢(只是爲了查看連接是否正在工作)「SELECT a FROM AName a LEFT JOIN a.aNameRoleList r WHERE r.inactiveflag ='N'」(無獲取),它將返回記錄。看來,我不需要獲取至少不與EclipseLink。不過,我明白你看過代碼。它讓我對命名查詢更有信心,所以我嘗試了一些其他的東西,我將它們放在一個單獨的答案中。 – Steve