Patrick
Patrick

Reputation: 15

In Spring-Roo 2.0, the JSON I get does not show relationship between objects.

This is a simplified example of the problem I'm having with Spring-Roo 2.0 returning JSON from the RESTful web-service call. Below are the Roo script for 2 classes (company, and user), the database content showing that the user is related to company_id=1, and the JSON I get back for the GET on the user. Note that company=null. That's the problem. Am I doing something wrong?

Roo Script

jpa setup --provider HIBERNATE --database MYSQL 
--userName pivot --password pivot  --databaseName testdb

entity jpa --class ~.model.MyUser
field string --fieldName firstName --notNull
field string --fieldName lastName --notNull

entity jpa --class ~.model.Company
field string --fieldName name –notNull

field set --fieldName users --type ~.model.MyUser --cardinality ONE_TO_MANY 
      --mappedBy company --comment "Users" --notNull false

repository jpa --all --package ~.repository
service --all --apiPackage ~.service.api --implPackage ~.service.impl
web mvc setup

/* ThymeLeaf view layer */
web mvc view setup --type THYMELEAF
web mvc templates setup --type THYMELEAF
web mvc controller --all --package ~.web --responseType THYMELEAF

/* JSON Rest controllers */
web mvc controller --all --responseType JSON --pathPrefix /json

web mvc finder --all --responseType THYMELEAF
web mvc finder --all --responseType JSON

Database

mysql> select * from my_user;
+----+------------+-----------+---------+------------+
| id | first_name | last_name | version | company_id |
+----+------------+-----------+---------+------------+
|  1 | First      | Last      |       0 |          1 |
+----+------------+-----------+---------+------------+
1 row in set (0.00 sec)

JSON

{
    "content": [
        {
            "id": 1,    
            "version": 0,
            "firstName": "First",
            "lastName": "Last",
            "company": null
        }
    ],
    "last": true,
    "totalPages": 1,
    "totalElements": 1,
    "size": 20,
    "number": 0,
    "first": true,
    "numberOfElements": 1,
    "sort": null
}

Upvotes: 1

Views: 271

Answers (1)

jcgarcia
jcgarcia

Reputation: 3882

The relationships generated by Spring Roo 2.0 are setted as Lazy by default to prevent data overload. Remember that Spring Roo tries to apply the best practises as possible. You could see this in your MyUser.java entity:

@ManyToOne(fetch = FetchType.LAZY)
@EntityFormat
private Company company;

So, when you are obtaining all the records of MyUser entity, the relationships with Comapny are not loaded by default.

However, If you know that you want to obtain this information, you should customize the generated code by Spring Roo. Follow these steps:

Make push-in of the method findAll declared in theMyUserRepositoryImpl class. To do it, execute the following command:

push-in --class ~.repository.MyUserRepositoryImpl --method findAll(GlobalSearch,Pageable)

After that, open the MyUserRepositoryImpl.java class and change the default query to execute a left join with Company. To do that, change this generated code:

JPQLQuery<MyUser> query = from(myUser);

to this one:

JPQLQuery<MyUser> query = from(myUser).leftJoin(myUser.company).fetchJoin();

Repeat the process with the findOne method that is used when you try to obtain an individual item instead of a list. In this case, you should define the findOne method in the MyUserRepositoryCustom interface and after that, implement it using QueryDSL in MyUserRepositoryImpl.

With the changes above, you should be able to obtain the following JSON when you acces to the url http://localhost:8080/json/myusers/ using GET operation:

{
  "content": [
    {
      "id": 1,
      "version": 0,
      "firstName": "test",
      "lastName": "test",
      "company": {
        "id": 1,
        "version": 0,
        "name": "aaa"
      }
    }
  ],
  "last": true,
  "totalPages": 1,
  "totalElements": 1,
  "sort": null,
  "numberOfElements": 1,
  "first": true,
  "size": 20,
  "number": 0
}

As an advice, I have to say that you should be careful when you use entities with relationships in JSON responses. Maybe you could get a cyclic relationship if some entity is related with other entity that is related with the first one. Instead of return the complete entity in your JSON responses, you should return an entity projection that only shows the identifier of the related element instead of the entire related entity.

Hope it helps,

Upvotes: 2

Related Questions