java - Spring REST Hibernate 应用设计

标签 java spring hibernate rest spring-mvc

环境:

Spring 4 休息

Spring MVC

hibernate

问题:

我们正在开发具有以下堆栈的应用程序。

enter image description here

Spring REST Web 服务将为客户端公开 API,客户端将在 UI (ASP .NET) 上显示它。响应以 JSON 格式发送。

考虑以下场景:

客户端调用 REST api 以获取具有 ID 的用户。 dao 层获取用户实体并将交付给客户端。

以及上述场景的以下问题/观察结果:

  1. 由于 User 可以通过 Hibernate 映射(例如使用 oneToMany 的 userRoles)与其相关的其他实体,因此也需要获取这些实体,否则会抛出 LazyInitialization 异常,因为 UI 会尝试通过 User 对象访问这些集合。

  2. 并非用户对象中的所有属性都需要响应(例如:某些请求不需要用户拥有的角色)。

考虑到上面的图片,通过 Spring REST 将用户对象(或响应)发送到客户端的最佳设计方法是什么?

  1. 创建模仿实体对象的对象中间层(如 DTO)。根据要求将此 DTO 填充到服务层中。由于服务层在事务内部运行,第 1 个问题将得到解决。但这需要在实体和 DTO 之间进行额外的复制

  2. 在 Hibernate 实体/查询级别处理第 1/2 号问题(加入提取查询或修改映射)并通过注释排除响应中不需要的属性,例如:@JsonIgnore。但是这种方式不够灵活,需要非常仔细地设计实体类

有人可以对此发表评论吗? 有没有更好的选择?

最佳答案

我强烈建议使用 DTO 级别,原因如下:

  1. 在某些时候,您的 REST 表示不会与 DAO 实体完全匹配。以下是几个示例:

    • 您需要为您的应用程序的移动版本返回轻量级用户信息的完整列表(仅用户的名字和姓氏)
    • 你想提供从 DAO 加载的用户信息 + 一些支付账户信息,从单独的服务中检索。
    • 您想将来自两个独立 DAO 实体的信息合并到一个服务调用中
    • 等等
  2. 缓存数据使用一些第 3 方库(EhCache、Hazelcast 等)或简单的类似 Map 的结构 - Hibernate 实体的自定义序列化可能成为具有复杂关系的实体的一大难题.

  3. 在 DTO 级别,您可以将服务接口(interface)/DTO 作为接口(interface)/客户端库与其他组件集成。您仍然可以安全地修改/完全重新设计您的 DAO 层实现,例如甚至切换到无 SQL 解决方案。

作为结论 - 在 REST API 中使用 Hibernate 实体适用于简单的“Hello World”应用程序,但不适用于大多数现实生活中的解决方案。

关于java - Spring REST Hibernate 应用设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34461140/

相关文章:

java - Play Framework 中的 SBT 找不到 org.hibernate 依赖项

javascript - Websockets-多种消息类型

java - 使用 SpEL 复制 bean 的引用不起作用

java - Spring boot - 在创建时设置动态属性

java - 如何在不专门使用 Spring ApplicationContext 的情况下检索 beansOfType(Class) 列表?

java - Spring 安全。删除一个拦截 URL 后不重定向到登录页面

java - 注释ManyToMany唯一关键问题

java - 类转换异常 : LinkedHashMap cannot be cast to custom object using a Comparator in Java

hibernate - 此位置不允许查询注释

java - hibernate 是否检查对象是否实际上已更改,还是假设 setter 是否被调用?