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预期的记录。
几天来我一直在为命名查询而苦苦挣扎。命名查询具有到第二个 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预期的记录。