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

时间:2017-06-08 21:34:37

标签: json spring-roo

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

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

数据库

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
}

1 个答案:

答案 0 :(得分:2)

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

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

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

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

插入findAll类中声明的方法MyUserRepositoryImpl。为此,请执行以下命令:

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

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

JPQLQuery<MyUser> query = from(myUser);

到这一个:

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

使用尝试获取单个项而不是列表时使用的findOne方法重复此过程。在这种情况下,您应该在findOne界面中定义MyUserRepositoryCustom方法,然后在MyUserRepositoryImpl中使用QueryDSL实现它。

通过上述更改,当您使用http://localhost:8080/json/myusers/操作访问网址GET时,您应该能够获得以下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响应中使用具有关系的实体时应该小心。如果某个实体与与第一个实体相关的其他实体相关,也许您可​​以获得循环关系。您应该返回仅显示相关元素的标识符而不是整个相关实体的实体投影,而不是返回JSON响应中的完整实体。

希望它有所帮助,