2017-03-02 79 views
1

假设有两个实体 - 业主Hibernate HQL“加入的路径!” @ManyToOne关系

@Entity 
@NamedQueries({ 
    @NamedQuery(name = "Owner.findOwnerForPetId", query = "select o from Owner o inner join Pet p on o.ownerId=p.owner.ownerId where p.petId= :petId") 
}) 
public class Owner { 

    @Id 
    @Column(name = "ownerId") 
    private Long ownerId; 

    @Column 
    private String name; 

    // scaffolding code... 
} 

和宠物

@Entity 
public class Pet { 

    @Id 
    @Column(name = "petId") 
    private Long petId; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "ownerId") 
    private Owner owner; 

    @Column 
    private String name; 

    // scaffolding code... 
} 

,其中一个业主可以有多个宠物(原班分别更名),但是一个宠物只能属于一个所有者。我想要做的是找到所有者拥有一个有一些id的宠物,如:

select Owner.ownerId, Owner.name from Owner inner join Pet on Owner.ownerId=Pet.ownerId where Pet.petId=3; 

这在纯SQL中执行时工作正常。不过,我曾尝试在HQL这两个查询,他们都给予了错误Path expected for join!

select o from Owner o inner join Pet p on o.ownerId=p.owner.ownerId where p.petId= :petId 

from Owner o join Pet p where p.petId= :petId 

注意,有业主在没有@OneToManyCollection<Pet> pets。我想在宠物方面只有@ManyToOne

我错过了什么提示?

+0

“预期路径”意味着“所有者”无法访问宠物,除非它将它们存储在集合中。我相信你必须让'所有者'保持宠物的集合。 –

回答

1

试试这个

select o from Pet p inner join p.owner o where p.petId= :petId 
+0

它的工作原理!太感谢了。 –

1

当HQL工作,你必须使用不只是实体

所以INNER JOINLEFT JOIN,例如,你应该使用的关系实体之间的关系直接

例如下一个有效查询

选择o由PET p内加入p.ownerö WHERE p.petId =:petId (同@rathna接受的答案)

选择中的P由PET p WHERE p .owner.ownerId =:OWNERID

1

为了完整起见,如果你需要LEFT JOIN但有@ManyToOne属性在右侧,因此不能指定路径,您可以使用变换将查询变为RIGHT JOIN具有相同的效果。不会丢失其他表没有匹配行并且在不丢失空行的情况下过滤另一个表的行)。

假设你想获得不养宠物忽略名为查理宠物所有业主:

不能指定

SELECT o 
FROM Owner o 
LEFT JOIN o.pet p (<-------- ERROR) WITH p.name != 'Charly' 
GROUP BY o.ownerId 
HAVING count(p.petId) = 0 

但是你可以转换成这样:

SELECT o 
FROM Pet p 
RIGHT JOIN p.owner o WITH p.name != 'Charly' 
GROUP BY o.ownerId 
HAVING count(p.petId) = 0