Hibernate,在不加载关联实体的情况下获取外部id

vbe*_*nar 8 java hibernate

简单的例子:

映射:

@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;
...
Run Code Online (Sandbox Code Playgroud)

用法:

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);
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

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
Run Code Online (Sandbox Code Playgroud)

现在这是一种奇怪的行为.我可以获得Country对象(可能是一些代理),Hibernate还没有发出任何额外的SQL查询.但是当我调用country.getId()时 - hibernate会发出SQL查询来加载完整的国家/地区对象.很明显,Hibernate知道country.id值,所以我希望hibernate只返回该id而不需要任何额外的SQL查询.但事实并非如此.

问题是 - 我不需要整个实体.我只需要id,我不需要单独的SQL查询(如果我设置FetchType.EAGER,则不需要JOIN查询).

RE3*_*350 6

我想你必须Country像下面那样改变你的实体AccessType.在Id字段上添加注释.

@Entity
    public class Country {
        @Id@GeneratedValue@AccessType("property")
        private Integer id;

        private String name;
Run Code Online (Sandbox Code Playgroud)

面对类似的问题,并按照这篇文章: - 访问者类型注释