我目前正在使用以下组件开发分布式应用程序:
1.tier:数据库服务器 -> MySQL 5.5
2.层:应用程序服务器 -> Glassfish 3.1.2.2
3.tier:独立 Fat-Client -> Java-SE (JRE 6)
我使用 JPA 2.0 (eclipse-link) 作为持久性提供程序,目前使用序列化在第二层和第三层之间传递 @Entity beans。我使用静态编织是为了从 JPA 支持的延迟获取中受益。
我的问题是,由于第二层/第三层之间的序列化,延迟获取将不起作用!这会导致网络流量过大,因为我的实体 bean 之一的每次序列化都要求在通过网络发送之前获取与其他实体/表的所有关系。
在这样的设置中我如何从 JPA 延迟获取中受益?是否有一种解决方法,无需引入轻量级 DTO/DAO(这会给我的项目增加巨大的复杂性)?
非常感谢您提前提供的帮助!
最佳答案
根据我在类似架构上的经验,对于一个相当大的项目,DTO是不可避免的,应该在必要时使用。
使用分离的实体,特别是当它们与其他实体有多个关联时,不仅会因数据库加载和序列化而导致性能问题,而且会带来巨大的复杂性。事实上,除非代码有很好的文档记录,否则很难在表示层中知道给定的关联是否已加载,这会导致大量延迟初始化异常。
如果您将序列化的分离实体从表示层发送回服务层,情况会更糟,因为这样您最终会得到使用分离实体和附加实体混合的代码,这会使事情变得更加复杂。
我的建议是:
- 如果实体很简单并且UI层不需要太多加载的关联,则将实体从服务层转移到UI层。始终记录哪些关联已初始化,哪些未初始化。如果关联太多,请使用 DTO 和即席查询从数据库加载必要的数据。
- 当需要大量实体时(例如,搜索表单返回 O(100) 个结果或更多),将 DTO 从服务层转移到 UI 层。使用临时查询加载请求的数据。
- 避免将实体从表示层传输到服务层。如果这样做,请确保在服务层中执行的第一件事是从数据库重新加载实体的附加版本,或合并接收到的实体,以便始终使用附加实体。调试在服务层中抛出的延迟初始化异常(由于使用了几分钟前由前一个屏幕加载的分离实体而导致)并不是一件令人愉快的事情。
关于Java-EE : How to design data flow in a 3-tiered application environment?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12528502/