我需要一些有关在Java中设计N层系统的“集成层”的建议。该层负责持久化和检索“业务层”(位于单独的服务器上)的数据。我是J2EE的新手,并且已经阅读了几本书和博客。技术首字母缩略词的字母汤使我感到困惑,所以我有几个问题。
首先,到目前为止,我已经掌握了什么:我正在使用JPA(通过Hibernate)将数据持久化并检索到数据库中。我制作了数据访问对象EJB,并计划将其部署到应用程序服务器(JBoss),这使事务更加容易(它们在我的DAO的功能级别上),而且我不必担心获得EntityManager的句柄(依赖注入)。这是一个什么样的例子:
@Entity
class A{
@Id
Long id;
@OneToMany
List<B> setOfBs = new ArrayList<B>;
}
@Entity
class B{
@Id
Long id;
}
@Remote
public interface ADAO{
public A getAById(Long id);
}
@Stateless
class ADAOImpl implements ADAO{
@PersistenceContext
EntityManager em;
public A getAById(Long id){ ... }
}
我的问题是:业务层应如何与集成层交换数据。我已经阅读了RESTful服务,它们看起来很简单。我关心的是获取和设置的频率增加时的性能(HTTP通信似乎并不特别快)。另一种选择是RMI。我的DAO已经是EJB。我可以直接让业务层(通过JNDI)访问它们吗?如果是这样,如果延迟加载上面示例中的@OneToMany链接,会发生什么情况?
例如,如果业务层执行以下操作:
Context context = new InitialContext(propertiesForIntegrationTierLookup);
ADAOImpl aDao = (ADAOImpl) context.lookup("something");
A myA = aDao.getAById(0);
int numberOfBs = myA.setOfBs.size();
如果setOfBs列表是延迟加载的,那么当业务层(在单独的服务器上)访问列表时,大小是否正确?列表是否可以通过EJB的魔力正确加载?如果没有(我期望),那么解决方案是什么?
抱歉,很长的帖子。就像我说的那样,我是J2EE的新手,并且我已经读了足够的东西来获得一般性的想法,但是在将各个部分组合在一起时我需要帮助。
最佳答案
当您在惰性集合上调用size()时,它将被初始化,因此无论使用哪种接口-Remote或Local,您都将始终获得正确的大小。
另一种情况是,您试图将JPA类用作数据传输对象(DTO)并通过Remote接口请求它们。我不记得这里有任何延迟的初始化问题,因为在传输之前,所有对象都必须在服务器端进行序列化(初始化了延迟集合)。结果,整个对象图通过网络传递,这可能会导致严重的cpu和网络开销。此外,要使反序列化成为可能,您将必须与远程应用程序共享JPA类。这就是“ EJB魔术”结束的地方和方式:)
因此,一旦可以进行远程调用,我建议开始考虑将数据传输策略和非JPA数据传输对象作为附加数据层。就我而言,我已经为XML绑定(JAXB)注释了DTO类,并在Web服务中重用了它们。