Hibernate HQL带select子句查询报InvalidPathException问题求助
刚接触Hibernate与HQL,现有Employee、Person、House三个实体类,尝试执行HQL语句:select person from Employee where house.id=:houseId
以获取指定houseId对应的Person对象,但触发了InvalidPathException和QuerySyntaxException;而去掉select子句的语句from Employee where house.id=:houseId可正常运行。仅需获取Person对象,请问问题出在哪里?
Employee实体类
public class Employee implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column private Integer authority; @Column private String username; @Column(name = "user_password") private String password; @Column private String title; @OneToOne @JoinColumn(name = "person_id", referencedColumnName = "id") private Person person; @Column private Integer gender; @Column private String ssn; @Column(name = "car_info") private String carInfo; @Column(name = "birth_date") private Date birthDate; //java.util Date vs java.sql.Date? @OneToOne @JoinColumn(name = "visa_status_id", referencedColumnName = "id") private VisaStatus visaStatus; @Column(name = "license_number") private Integer licenseNumber; @Column(name = "license_expiration_date") private Date licenseExpirationDate; @ManyToOne @JoinColumn(name = "housing_id", referencedColumnName = "id") private House house; }
Person实体类
public class Person implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(name = "first_name") private String firstName; @Column(name = "last_name") private String lastName; @Column(name = "middle_name") private String middleName; @Column(name = "preferred_name") private String preferredName; @ManyToOne @JoinColumn(name = "address_id", referencedColumnName = "id") private Address address; @Column private String email; @Column(name = "ceil_phone") private String ceilPhone; @Column(name = "work_phone") private String workPhone; }
House实体类
public class House implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @OneToOne @JoinColumn(name = "address_id", referencedColumnName = "id") private Address address; @ManyToOne @JoinColumn(name = "contact_id") private Contact contactHR; @ManyToOne @JoinColumn(name = "landlord_id") private Person landlord; }
报错信息
org.hibernate.hql.internal.ast.InvalidPathException: Invalid path: 'house.id' org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'house.id' [select person from example.project.domain.entity.Employee where house.id=:houseId]
问题根源
当你写select person from Employee where house.id=:houseId时,Hibernate会把查询结果的根对象切换成Person,后续的house.id会被解析成Person的属性,但Person里根本没有house这个关联,自然就报路径无效的错误。而不带select的语句from Employee where house.id=:houseId是以Employee为根对象,house是Employee的属性,所以能正常识别。
解决办法
最直接的方式是给Employee起别名,明确指定house是Employee的属性,让Hibernate正确解析路径:
select e.person from Employee e where e.house.id=:houseId
如果后续需要更灵活的关联查询,也可以给Person加上反向关联(在Person类里添加@OneToOne(mappedBy = "person") private Employee employee;),然后用关联查询的方式:
select p from Person p join p.employee e where e.house.id=:houseId
不过第一种办法不需要修改实体类,更适合当前场景。
内容的提问来源于stack exchange,提问作者CitoC

