带有Join的JPA NamedQuery返回空列表

时间:2016-05-27 21:53:05

标签: jpa inner-join named-query

我已经在命名查询中挣扎了好几天。命名查询具有到第二个表的内部联接。一个增加的复杂性是第二个表上的主键是复合键。我在这里简化了两个表格:

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'

谢谢,

史蒂夫

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

经过更多测试后,我意识到加入工作正常,但不是&#34; r.aNameRolePK.nametype =&#39; 5&#39;&#34;。但是,如果我将其更改为&#34; r.aNameRolePK.nameidx = 1&#34;有用。所以,它只是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

返回预期记录。