我可以使用什么而不是实体bean?

时间:2013-09-08 23:22:03

标签: java java-ee entity ejb-3.2

我想编写一个用于在线学习的Java EE应用程序。我正在考虑这种数据表示:

@Entity
public class Course {
    private String name;
    private String[] instructors;
    private String[] teachingAssistants;
    private GradeBook gradeBook;

    // plenty of methods
}

@Entity
public class GradeBook {
    private GradeBookColumn[];

    // some methods
}

@Entity
public abstract class GradeBookColumn {
    private String name;
    private GradeBookColumnType type;

    // more methods
}

我会有更多不仅仅是这个,但你明白了。

现在,在EJB 3.2规范中,实体bean被删除并替换为JPA实体。我的问题是如何应对这一悲惨的损失。序列化JPA实体不适合我的原因有三个:

  1. 效果。我需要通过网络推送整个实体及其所有数据。这些数据非常多,而且可能需要很长时间才能完成。
  2. 安全性。如果实体中的所有数据都通过网络传输,则下载它的程序可以访问所有数据。但是,如果用户具有足够的权限,我希望只能访问某些数据。
  3. 写入权限。下载完数据副本后,客户端应该能够对其进行更改。但是,如果进行了更改,它们将不会持久保存到服务器。当然,我总是可以将实体发送回服务器进行保持,但我必须通过更慢的上游连接发送所有数据。
  4. 那么,如何在没有实体bean的情况下设计此系统以满足这些要求?

1 个答案:

答案 0 :(得分:1)

我不确定实体bean的损失是否真的很悲惨,但这是一个意见问题:)

您似乎在桌面上有一个连接到远程服务器的富客户端。您有两种选择:

一个。您在客户端和服务器之间交换“detached”对象图。客户端接收一些数据,修改它,然后将其发回。然后服务器“merges”收到它的数据。加载数据时服务器上有一个事务,合并后有一个事务。为确保您没有冲突,您可以对数据进行版本控制。

B中。您使用“extended persistence context”。在这种情况下,客户端会收到仍然“附加”到会话的entites。缓存客户端实体的修改,并在服务器上调用方法时进行同步。

所以,关于你面临的三个设计问题,这是我的看法:

  1. 性能。 JPA和其他现代ORM依赖于懒惰以避免不必要的数据传输:数据按需加载。您可以选择热切或懒散地加载图形的哪个部分。使用选项A,您需要确保在将所有必要数据发送到客户端之前加载它们;如果客户端尝试访问未加载的数据,则会收到异常,因为它在事务之外。使用选项B,我猜客户端可以随时延迟加载数据(值得仔细检查)。

  2. 安全性。 JPA实体应该是业务对象,而不是数据对象。它们可以封装执行必要检查的业务方法,并保留所需的不变量。换句话说:安全性不是在数据级别处理,而是在业务逻辑级别处理。这适用于选项A和B.

  3. 写访问。使用选项A,您需要发回整个图并合并它。使用选项B,框架应该以更优化的方式合并已缓存的更改。

  4. 结论:

    扩展持久性上下文已经设计用于具有长工作单元的GUI应用程序。他们理论上应该解决你的问题。实际上,扩展持久化上下文虽然具有复杂性(例如需要使用有状态会话bean)。

    分离和合并图表的方法更简单,但提出了您在性能方面提到的问题。

    第三种选择是回到传统的data transfer object (DTO)来优化性能。在这种情况下,JPA只能在服务器端保留。您只需将真正需要的数据子集转移到DTO中,而不是传输JPA entites。缺点是DTO会激增,您将拥有样板代码来从JPA entites创建DTO,并更新来自DTO的JPA enties。