[英]Hibernate, get foreign id without loading associated entity
簡單的例子:
映射:
@Entity
public class City {
@Id@GeneratedValue
private Integer id;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
private Country country;
...
@Entity
public class Country {
@Id@GeneratedValue
private Integer id;
private String name;
...
用法:
Query query = session.createQuery("from City");
List<?> cities = query.list();
for (Object cityObj : cities) {
City city = (City) cityObj;
System.out.printf("City: %s %s%n", city.getId(), city.getName());
Country country = city.getCountry();
System.out.println("Country retrieved");
Integer countryId = country.getId();
System.out.printf("Country id: %s%n", countryId);
}
這是輸出:
Hibernate: select city0_.id as id0_, city0_.country_id as country3_0_, city0_.name as name0_ from City city0_
City: 1 Astana
Country retrieved
Hibernate: select country0_.id as id1_0_, country0_.name as name1_0_ from Country country0_ where country0_.id=?
Country id: 1
City: 2 Almaty
Country retrieved
Country id: 1
City: 3 Omsk
Country retrieved
Hibernate: select country0_.id as id1_0_, country0_.name as name1_0_ from Country country0_ where country0_.id=?
Country id: 2
現在這是一種奇怪的行為。 我可以獲得Country對象(可能是一些代理),Hibernate還沒有發出任何額外的SQL查詢。 但是當我調用country.getId()時 - hibernate會發出SQL查詢來加載完整的國家/地區對象。 很明顯,Hibernate知道country.id值,所以我希望hibernate只返回該id而不需要任何額外的SQL查詢。 但事實並非如此。
問題是 - 我不需要整個實體。 我只需要id,我不需要單獨的SQL查詢(如果我設置FetchType.EAGER,則不需要JOIN查詢)。
我認為你必須像下面AccessType
改變你的Country
實體。在Id字段上添加AccessType
注釋。
@Entity
public class Country {
@Id@GeneratedValue@AccessType("property")
private Integer id;
private String name;
面對類似的問題,並按照這篇文章: - 訪問者類型注釋
所以正確的JPA標准解決方案將是:
@Entity
public class Country {
@Id @GeneratedValue @Access(PROPERTY)
private Integer id;
只是想加入@ RE350的答案。
在Hibernate 5.2.15中,如果您使用的是CriteriaQuery
。 然后,這可以很容易地完成,而不需要@AccessType
注釋。(已經棄用了@AttributeAccessor
)。
final CriteriaBuilder cb = criteriaBuilder();
final CriteriaQuery<City> query = criteriaQuery();
final Root<City> q = query.from(City.class);
final Path<Integer> uid = q.get("country").get("id"); // Note this!!
注意 :您也可以像這樣獲取國家/地區,在這種情況下,它實際上會加入表格。
final Path<Integer> uid = q.join("country").get("id");
更新:
但是,對於ManyToMany連接,這似乎並不容易,除非您有一個實體來為ManyToMany表建模。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.