Hibernate HQL "Path expected for join!" @ManyToOne 关系
Hibernate HQL "Path expected for join!" @ManyToOne relationship
假设有两个实体 - 所有者
@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...
}
其中一个主人可以拥有多只宠物(原class已改名),但一只宠物只能属于一个主人。我想做的是找到拥有宠物的主人,宠物有一些 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
请注意,所有者中没有 @OneToMany
或 Collection<Pet> pets
。我想在宠物方面只使用 @ManyToOne
。
有什么关于我遗漏的提示吗?
试试这个
select o from Pet p inner join p.owner o where p.petId= :petId
使用 HQL 时,您必须使用实体之间的关系,而不仅仅是实体
所以对于 INNER JOIN 和 LEFT JOIN 例如你应该使用关系 direct
例如,接下来是有效查询
SELECT o FROM Pet p inner join p.owner o WHERE p.petId= :petId (same as @rathna accepted answer)
SELECT p FROM Pet p WHERE p.owner.ownerId = :ownerId
为了完整起见,如果你需要LEFT JOIN但是右边有@ManyToOne属性,因此可以如果不指定路径,您可以将查询 transform 转换为具有相同效果的 RIGHT JOIN (即不会丢失其他 table 没有匹配的行并过滤其他 table 而不会丢失空行)。
假设您想让所有没有宠物的主人忽略名为 Charly 的宠物:
你不能指定
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
假设有两个实体 - 所有者
@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...
}
其中一个主人可以拥有多只宠物(原class已改名),但一只宠物只能属于一个主人。我想做的是找到拥有宠物的主人,宠物有一些 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
请注意,所有者中没有 @OneToMany
或 Collection<Pet> pets
。我想在宠物方面只使用 @ManyToOne
。
有什么关于我遗漏的提示吗?
试试这个
select o from Pet p inner join p.owner o where p.petId= :petId
使用 HQL 时,您必须使用实体之间的关系,而不仅仅是实体
所以对于 INNER JOIN 和 LEFT JOIN 例如你应该使用关系 direct
例如,接下来是有效查询
SELECT o FROM Pet p inner join p.owner o WHERE p.petId= :petId (same as @rathna accepted answer)
SELECT p FROM Pet p WHERE p.owner.ownerId = :ownerId
为了完整起见,如果你需要LEFT JOIN但是右边有@ManyToOne属性,因此可以如果不指定路径,您可以将查询 transform 转换为具有相同效果的 RIGHT JOIN (即不会丢失其他 table 没有匹配的行并过滤其他 table 而不会丢失空行)。
假设您想让所有没有宠物的主人忽略名为 Charly 的宠物:
你不能指定
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