我已经在命名查询中挣扎了好几天。命名查询具有到第二个表的内部联接。一个增加的复杂性是第二个表上的主键是复合键。我在这里简化了两个表格:
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 :(得分: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
返回预期记录。