A simple example:
display:
@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; ...
using:
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); }
here is the conclusion:
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
Now that is weird behavior. I can get the Country object (maybe some proxy), and Hibernate has not yet issued any additional SQL queries. But when I call country.getId () - hibernate issues an SQL query to load the full country object. Obviously, Hibernate knows the value of country.id, so I expected hibernate to simply return this identifier without any additional SQL queries. But this is not so.
The problem is that I do not need this object. I only need the identifier, and I do not want a separate SQL query (or JOIN query if I install FetchType.EAGER).
source share