EJB 3.0 (JPA) 的 Persistence Context
大家在使用 EJB 3.0 的时候会注意到 EJB 3.0 中的容器管理 Persistence Context 有两种类型,一种是 Transaction,另一种是 Extended。这是一个较 Hibernate 的 Session 所没有的概念,Session 没有两种不同的类型,而且最重要的是 Session 不是容器管理的,这里的容器指的是 App Server 容器。这里暂时不谈论 Persistence Context 与 Session 之间的异同,主要谈谈两种 Persistence Context 之间的不同。学过 ORM 的同学都知道,当 Persistence Context 是打开状态的时候,Model 就处于被管理的状态中;当 Persistence Context 关闭之后,Model 就处于了 Detached 状态。
上面这些特性对于 Transaction 或 Extended 的 Persistence Context 都是一样的,不同的地方在于 Persistence Context 何时被打开关闭。由于绝大多数情况下 Persistence Context 是被容器管理的(如果你不嫌累也可以自己控制 Persistence Context),所以在 EJB 3.0 应用中看不到打开或关闭 Persistence Context 的代码(Spring + Hibernate 的应用也同样如此,Hibernate Session 的管理工作可以交给 Spring 来做)。
其实,Transaction 和 Extended Persistence Context 的不同之处也就在于容器何时打开或关闭 Persistence Context。Transaction 类型的 Persistence Context 的打开和关闭是和事务的打开和关闭是同步的。也就是说在一个事务开始之后,Persistence Context 才会开始;在事务关闭的时候,相应的 Persistence Context 也会被关闭。
Extended 类型的 Persistence Context 的打开和关闭是和 Stateful Session Bean 的生命周期同步的,是跨越事务的。也就是说,从 SFSB 的初始化开始,直到销毁,Persistence Context 都是存在的。你可以在事务之外执行写操作,但是这是并不会执行真正的数据库操作,写操作只是放入了队列,直到下一个事务,写操作才会真正地被执行。两者的不同简单说来就是 Extended Persistence Context 存在的时间更长。那为什么要有两种不同的 Persistence Context 呢?
当一个 Web 请求到来时,服务器会打开一个线程,这个线程可能会调用一个事务方法,这是一个事务便开始了,当这个请求结束时,线程关闭,事务也随之结束。由于 Transaction 类型的 Persistence Context 的生存周期是在事务范围之内的,所以一个 Web 请求的结束也意味着相应的 Persistence Context 的关闭。由于多数 Web 应用在一次 Web 请求内即可完成一个独立的操作,所以大部分情况下 Transaction 的 Persistence Context 是适用的。但是对于一些复杂的应用,一次操作需要跨越多次请求。这种情况下,如果依旧使用 Transcation 的 Persistence Context,由于每次请求结束后,相应的 Persistence Context 都被关闭,相应的 Model 也就变为 Detached 状态。如果接下来的请求仍然需要这些已经变为 Detached 状态的 Model 就需要重新 load,使用 merge() 方法来持久化。稍有不适就会产生 LazyInitializationException 和 NonUniqueObjectException。同时,这也提高了操作的复杂程度。
如果使用 Extended Persistence Context 就能解决这些问题。由于 Extended Persistence Context 的生命周期是与 SFSB 的生命周期同步的,所以只要多次请求调用的都是同一个 SFSB 中的方法,有多少次的请求,Persistence Context 总是同一个,其中的 Model 也始终是被管理的。很好地解决了 Persistence Context 在线程之间传递的问题,也不会有 LazyInitializationException 和 NonUniqueObjectException 问题的发生。
Seam-managed Persistence Context
EJB 3.0 容器管理之下的 Persistence Context 很不错,能解决很多问题,但是还是有些问题无法解决。Seam 很强大,如果有些问题 EJB 容器解决不了了,没关系,把 Persistence Context 交由 Seam 来管理就 OK 了。那 Seam 都能解决哪些 EJB 不能解决的问题呢?先考虑下面两个问题:
1. Extended Persistence Context 虽然可以跨越多个事务,但是每个事务照旧调教不误,这对于想在想让整个操作作为一次事务的话,该如何去做
2. 如果一个业务的一组请求只是调用同一个 SFSB 的话,那么 EJB 的 Extended Persistence Context 可以在线程之间传递,使 SFSB 的整个生命周期都使用同一个 Persistence Context。但如果业务需要调用不同的 SFSB 的话,如何在 SFSB 之间传递。
对于第一个问题,由于 Seam 的 JPA 实现提供者是 Hibernate,而且 Hibernate 提供了一个扩展的 FlushModeType - "Manual"。通过使用这个 FlushModeType,我们可以手工控制何时执行 flush() 操作。在 Seam 的文档中有关于这部分的介绍 《Seam-managed persistence contexts and atomic conversations 》。文档中使用了一段简单的代码展示 Seam 如何实现所谓的 "atomic conversations"(关于代码的内容我就不介绍了,大家通过我提供的链接来浏览 Seam 的文档)。通过这种方式,事务貌似是跨越了整个事务,但我认为 SFSB 中除了调用 flush() 的方法以外的其它方法不是事务的。其实也没有必要,因为这些方法并没有执行数据库操作,所以没有必要使用事务。当然,如果是乐观事物的话,使用了对性能影响也不大(这只是我的一点浅薄的理解,欢迎指出错误)。只有最后的调用了 flush() 的方法有事务的必要。
这就引发了一个令我不解的问题。请先看这篇文章《Extended Persistence Context in Stateful Session Beans 》。在这篇文章介绍了如何只使用 EJB 3.0 去解决“问题1”。文中的 SFSB 的默认事务属性是 "NOT_SUPPORTED",也就是说这个 SFSB 中的方法默认不是事务的。只有最后的调用 flush() 的方法使用了 "REQUIRED" 的事务属性去覆盖默认设置。也就是最后的方法是事务的,其它的不是。这和 Seam 所做的有区别吗?感觉没有区别。但我认为像 Gavin King 这样的大牛绝不会做无用功的,那问题就是 Seam 实现 "atomic conversations" 的内部细节到底是什么呢?欢迎大家回答这个问题。
对于第二个问题,可以通过使用 Seam-Managed Persistence Context 来解决。Seam-manged Persistence Context 需要在 components.xml 文件中进行配置,并使用 @In 注入到 Seam 的组件中。由于 Seam 是一个比较新的框架技术,所以关于 Seam 是如何使 Persistence Context 在组件中传递并没有详细的介绍。应该只是声明,然后透明地使用即可。在一个 jBPM 流程中被使用到的 Seam 组件,其中的 Persistence Context 应该是可以很容易地被传递。(本不应该使用不确定的和模糊的词语,但无奈现在关于 Seam 的文章资料还是有限,所以我也没有找到关于 Persistence Context 在组件之间调用的例子)
分享到:
相关推荐
在"ejb3.0入门经典教程-source"这个压缩包中,包含了书中各个章节的示例代码,覆盖了EJB 3.0的各个方面,例如实体Bean的创建、会话Bean的使用、事务管理、安全性设置以及JPA的持久化操作等。这些源码对于初学者来说...
4. **查询语言(JPA & JPQL)**:EJB 3.0引入了Java Persistence API(JPA),其中包含Java Persistence Query Language(JPQL),这是一种面向对象的查询语言,用于从数据库检索和操作实体Bean。 5. **依赖注入...
- 简化的持久化:通过JPA(Java Persistence API),可以直接在实体类上使用注解进行数据映射,简化了对象关系映射。 - 更好的可测试性:无状态会话Bean易于进行单元测试,因为它们不依赖于持久性或会话状态。 7....
这本书主要关注于EJB 3.0 Java Persistence API(JPA),这是Java平台中用于持久化数据的重要组件。EJB 3.0是Java EE 5规范的一部分,它极大地简化了EJB的使用,降低了开发企业级应用的复杂性。 EJB 3.0的核心改进...
2. **实体bean的简化(Simplified Entity Beans)**:EJB3.0中,实体Bean不再需要实现特定接口,而是通过注解直接将类标记为实体,并且支持JPA(Java Persistence API),与ORM框架如Hibernate集成,大大简化了数据...
同时,EJB 3.0支持JPA(Java Persistence API),允许开发者使用Hibernate、TopLink等持久化框架。 2. **会话Bean(Session Beans)**:会话Bean用于处理业务逻辑。EJB 3.0允许开发者使用无状态会话Bean(`@...
### Java Persistence API (EJB 3.0 中的 JPA 规范说明) #### 引言 Java Persistence API(简称 JPA)是 Java 社区规范 JSR 220 的一部分,它定义了一种对象关系映射工具的标准,允许 Java 开发人员将 Java 应用...
2. **实体bean(Entity Beans)**:EJB3.0引入了JPA(Java Persistence API),使得对象关系映射(ORM)更为方便。你可以使用`@Entity`注解定义一个持久化类,然后通过`@Id`注解指定主键字段。JPA允许你直接操作对象...
1. **实体Bean(Entity Beans)**:EJB 3.0引入了JPA(Java Persistence API),这使得实体Bean的定义变得更加简单。开发者可以利用注解(Annotations)直接在实体类上定义数据映射,而不再需要XML配置文件。例如,`...
4. **Persistence Context**:EJB3.0中的JPA引入了Persistence Context概念,它管理着与数据库交互的对象生命周期。在 Persistence Context 内部,对象的持久化状态被跟踪,可以进行自动的脏检查和事务提交,简化了...
`ejb3-persistence-api`是Java企业版(Java EE)的一部分,它定义了用于持久化对象到数据库的标准API,即Java Persistence API(JPA)。这个API在ejb3-persistence.jar中实现,提供了强大的ORM(对象关系映射)能力...
《APress Pro EJB 3 Java Persistence API》一书由Mike Keith和Merrick Schincariol共同编写,出版于2006年,是关于Java Persistence API(JPA)与Enterprise JavaBeans(EJB)3的深入研究。本书旨在为读者提供关于...
其中,JPA(Java Persistence API)是EJB的一部分,用于处理对象关系映射(ORM),使得Java对象可以直接与关系数据库进行交互。 **JPA介绍** JPA是Java社区对ORM的一种规范,它的目标是提供一种统一的标准API,以...
EJB3.0另一个重大改变是引入了Java Persistence API(JPA)来替代EJB2.0的实体Bean。JPA允许直接将领域模型类(Domain Model)持久化到数据库,避免了EJB2中实体Bean和Model类之间的转换。EntityManager作为JPA的...
根据提供的文件信息,我们可以推断出这本书主要关注的是EJB 3.0(Enterprise JavaBeans)中的Java Persistence API(JPA)。以下是对该主题的一些关键知识点的总结与扩展。 ### EJB 3.0简介 EJB 3.0是Java EE平台...
2. **持久化**:EJB 2.0的Entity Beans依赖于Entity Bean容器,而EJB 3.0引入了JPA(Java Persistence API),允许开发者使用ORM(Object-Relational Mapping)框架,如Hibernate,进行数据持久化。 3. **事务管理*...
2. **持久化上下文(Persistence Context)**:了解JPA中的持久化上下文是如何管理和跟踪实体状态的,包括瞬时(Transient)、持久化(Persistent)、托管(Managed)和脱管(Detached)状态。 3. **数据访问接口...
JPA是Java标准,用来简化数据库操作,而EJB3则内建了对JPA的支持。 整合EJB3和Struts1.x的关键步骤包括: 1. **EJB3实体Bean**:创建EJB3实体Bean来代表数据库中的表,这些Bean通常会继承`javax.persistence....
- **持久化上下文(Persistence Context)**:JPA管理实体对象的状态,保证在一次会话内对同一实体的所有操作都是透明的。 - **查询语言(JPQL)**:JPA提供了一种面向对象的查询语言,类似于SQL但更面向对象,...