环境:
Spring 4 休息
Spring MVC
hibernate
问题:
我们正在开发具有以下堆栈的应用程序。
Spring REST Web 服务将为客户端公开 API,客户端将在 UI (ASP .NET) 上显示它。响应以 JSON 格式发送。
考虑以下场景:
客户端调用 REST api 以获取具有 ID 的用户。 dao 层获取用户实体并将交付给客户端。
以及上述场景的以下问题/观察结果:
由于 User 可以通过 Hibernate 映射(例如使用 oneToMany 的 userRoles)与其相关的其他实体,因此也需要获取这些实体,否则会抛出 LazyInitialization 异常,因为 UI 会尝试通过 User 对象访问这些集合。
并非用户对象中的所有属性都需要响应(例如:某些请求不需要用户拥有的角色)。
考虑到上面的图片,通过 Spring REST 将用户对象(或响应)发送到客户端的最佳设计方法是什么?
创建模仿实体对象的对象中间层(如 DTO)。根据要求将此 DTO 填充到服务层中。由于服务层在事务内部运行,第 1 个问题将得到解决。但这需要在实体和 DTO 之间进行额外的复制
在 Hibernate 实体/查询级别处理第 1/2 号问题(加入提取查询或修改映射)并通过注释排除响应中不需要的属性,例如:@JsonIgnore。但是这种方式不够灵活,需要非常仔细地设计实体类
有人可以对此发表评论吗? 有没有更好的选择?
最佳答案
我强烈建议使用 DTO 级别,原因如下:
在某些时候,您的 REST 表示不会与 DAO 实体完全匹配。以下是几个示例:
- 您需要为您的应用程序的移动版本返回轻量级用户信息的完整列表(仅用户的名字和姓氏)
- 你想提供从 DAO 加载的用户信息 + 一些支付账户信息,从单独的服务中检索。
- 您想将来自两个独立 DAO 实体的信息合并到一个服务调用中
- 等等
缓存数据使用一些第 3 方库(EhCache、Hazelcast 等)或简单的类似 Map 的结构 - Hibernate 实体的自定义序列化可能成为具有复杂关系的实体的一大难题.
在 DTO 级别,您可以将服务接口(interface)/DTO 作为接口(interface)/客户端库与其他组件集成。您仍然可以安全地修改/完全重新设计您的 DAO 层实现,例如甚至切换到无 SQL 解决方案。
作为结论 - 在 REST API 中使用 Hibernate 实体适用于简单的“Hello World”应用程序,但不适用于大多数现实生活中的解决方案。
关于java - Spring REST Hibernate 应用设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34461140/