在 Spring-Roo 2.0 中,我得到的 JSON 不显示对象之间的关系。

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

这是我在 Spring-Roo 2.0 从 RESTful 网络服务调用返回 JSON 时遇到的问题的简化示例。下面是 2 类(公司和用户)的 Roo 脚本,显示用户与 company_id=1 相关的数据库内容,以及我返回的 JSON GET在用户身上。请注意,company=null。那就是问题所在。我做错了什么吗?

Roo 脚本

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

数据库

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
}

由 Spring Roo 2.0 生成的关系默认设置为 Lazy 以防止数据过载。请记住,Spring Roo 尝试尽可能地应用最佳实践。您可以在 MyUser.java 实体中看到:

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

因此,当您获取MyUser实体的所有记录时,默认情况下不会加载与Compny的关系。

但是,如果您知道要获取此信息,则应通过 Spring Roo 自定义生成的代码。请按照以下步骤操作:

MyUserRepositoryImpl class 中声明的方法 findAll 进行推送。为此,请执行以下命令:

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

之后,打开 MyUserRepositoryImpl.java class 并更改默认查询以使用 Company 执行左连接。为此,请更改生成的代码:

JPQLQuery<MyUser> query = from(myUser);

给这个:

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

使用尝试获取单个项目而不是列表时使用的 findOne 方法重复该过程。在这种情况下,您应该在 MyUserRepositoryCustom 接口中定义 findOne 方法,然后在 MyUserRepositoryImpl.

中使用 QueryDSL 实现它

通过上述修改,当您使用GET操作访问urlhttp://localhost:8080/json/myusers/时,您应该能够获得以下JSON:

{
  "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
}

作为建议,我不得不说,在 JSON 响应中使用具有关系的实体时应该小心。如果某个实体与与第一个实体相关的另一个实体相关,也许您可​​以获得循环关系。您应该 return 一个 实体投影 而不是 return 您 JSON 响应中的完整实体,它只显示相关元素的标识符而不是整个相关实体。

希望对您有所帮助,