Hibernate, get an external identifier without loading an associated object

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).

+6
source share
2 answers

I think you will have to modify your Country object as shown below. Add AccessType annotation to the Id field.

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

Faced a similar problem and followed this article: Accessories type annotations

+6
source

So the right JPA standard solution would be:

 @Entity public class Country { @Id @GeneratedValue @Access(PROPERTY) private Integer id; 
+1
source

Source: https://habr.com/ru/post/980164/


All Articles