JPA NamedQuery with Join返回空列表

JPA NamedQuery with Join returning empty list

几天来我一直在为命名查询而苦苦挣扎。命名查询具有到第二个 table 的内部连接。一个增加的复杂性是 2nd table 上的主键是一个复合键。我在这里简化了两个 table:

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

还有一个主键classANameRolePK

@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 实体中指定的命名查询,以下 returns 一个空结果列表:

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

任何人都可以指出我在这个命名查询中做错了什么吗?

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

谢谢,

史蒂夫

默认情况下,至少在使用 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

经过更多测试后,我意识到连接有效,但 "r.aNameRolePK.nametype='5'" 无效。但是,如果我将其更改为 "r.aNameRolePK.nameidx=1" 它会起作用。所以,它只是名称类型字段,我们在数据库中将其定义为 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

这是returns预期的记录。