Why does JPA return the related records in FETCH LAZY?

0

I'm using JPA and I'm having problems retrieving records from tables that contain foreign keys, my DB is wide but I'll simplify the problem, in a typical REGION - > CITY - > COMUNA

REGION Table

Primary Key REGION

Table CITY

Primary Key CITY Foreign Keys CITY

COMUNA table

Primary Key COMUNA Foreign Keys COMUNA

I am executing simple sentences such as the following:

SELECT r FROM Region r
SELECT c FROM Ciudad c
SELECT c FROM Comuna c

With these queries, what I want is, in the first, all the records in the REGION table, in the second, all the records in the CITY table, in the third, all the records in the COMUNA table. But, for example for the query of COMUNA I am getting the following result:

And I get very similar results for the other two queries, I do not want this, I want, for the example that I pose, all the records of the COMUNA table without more, but it is bringing me the relationship and also that is not bringing all the records of the table COMUNA , only the first record ("Independence") and its relationships are bringing me, but that table has more records.

I am using Netbeans to generate the code automatically from the Entity Classes, and the Fetch by default is LAZY, I understand that this is fine. I am using Postgresql, I have already tried to change the LAZY by EAGER in the tables and the result is the same.

By the way, these examples are based in Chile, the country is divided into Regions, which in other countries are STATES and the Communes in other countries are called MUNICIPALITIES, it is only to put them a bit in context.

I know that a possible solution is not to inform the BD about the relationships between tables (Foreign keys), but that should not be the solution, that is, it is not the DUTY TO BE.

Here is the code I was asked for in the comments:

The implementation of the service

Netbeans generates an abstract, this is the abstract

These are the libraries that automatically generate me the JSON for exit and entry to the service, really I do not configure anything of these libraries, I only included them and they work so far for what I want that is to send and receive JSON without touching it

Here part of the code that generates netbeans, the rest are getters and setters

    
asked by Ricardo Gabriel 07.06.2018 в 17:20
source

1 answer

0

Marking a relationship like LAZY does not mean that JPA is not going to do anything with it when you recover the parent class. What JPA does is inform, with a special proxy class, the related attribute so that, for execution purposes, it does have value but until you do not actually access it, the query that retrieves the values of the relation is not executed.

Going to your specific case, that idRegion will be NULL in those cases in which Comuna has no relation with any Region. When that relationship does exist, the value of idRegion will not be a Region instance but an instance of a JPA proxy class.

When you are returning the list of Communities, the JSON converter finds that idRegion has value, so you access it to serialize it, at which time the query is executed and the values are retrieved.

To solve it you have two options:

  • Note with @JsonIgnore those attributes that are necessary in your entity but you do not want them to be serialized in the JSON response. This solution is not a panacea, because there could be cases where you want to recover the complete relationship, but that is already outside this question

  • Create a DTO class (ComunaDTO, for example) in which you do not include the relation with Region and, in your controller, instead of returning that List<Comuna> that you get from super.findAll() , you return a List<ComunaDTO> . This solution is also not perfect because you are creating "empty" classes that only serve to send data from one layer to another (anemic model). Also, what happens if, instead of just the base attributes of Comuna, you want to also include the id of the Region?

  • answered by 07.06.2018 в 18:04