这是我使用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
}
答案 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响应中的完整实体。
希望它有所帮助,