10、Rapid Seam development
This chapter covers
■ The Seam Application Framework
■ Building CRUD screens for an entity
■ Paginating and sorting a query result set
■ Assigning restrictions to queries
快速SEAM开发
本章涉及
SEAM应用框架
为实体建立CRUD页面
传播和排序一个查询结果集
对查询指定限制
If you think back to when you first learned golf—perhaps you are still learning—
you were probably overwhelmed with all of the things you have to concentrate
on at once. To start, you have to judge the distance you want to hit the ball and
choose the right club for it. This “design decision” is a tough call even for the best
golfers. Once your aim is set and you’re ready to take your swing, you have to position
your stance, set your grip, align the clubface, keep your head down, your
shoulders level, and your eye on the ball. It’s all so mechanical that even a good
swing feels unnatural.
如果你思考当你第一次学习高尔夫,你可能被立刻要面对地所有事吓倒。开始时,你必须判断你要打的距离而选择正确的杆,这种设计判断即使对最优秀的球员也是个艰难的决定。一旦你的目标已定,要去挥杆,你要定好你的击球姿势,设定你的行程、杆面,低头,肩水平,眼盯球。这些如此机械,甚至一个好的击球也显得不自然。
Then, one day, it all clicks. You stop thinking about every last detail and you just
swing. It’s hard to explain how you know—it just becomes natural to you, like walking
or riding a bike. When you look down the fairway, accounting for the obstacles
in front of you, you just get that sense of how far you want to send the ball and which
club to use to get it there. You are no longer “designing” your decisions based on
some prescribed distance chart, nor do you feel uncomfortable when you swing.
突然有一天,你不想再想每个细节了,你就是打。因为那已像走路和骑车一样自然了。靠的是感觉。想打多远,拿什么杆。你的打法不再由表格计算得出,你的感觉也不再不自然。
This chapter is the culmination of everything you’ve learned so far about Seam,
and it’s your chance to make things click. You’ll be combining components, component
instances, conversations, page parameters, page actions, navigation rules, managed
persistence, and transactions to implement several new features in the Open 18
application. By the end of this chapter, developing with Seam should feel so natural
that you’ll be able to assemble a custom application and still enjoy the fresh air. The
key to increasing your productivity with Seam is learning about the component templates
in the Seam Application Framework and knowing how to put them to use.
These templates enable you to develop rapidly by handling repetitive and mundane
tasks and putting Seam services close at hand. You’ll discover that these classes can be
put to use by extending them in Java, configuring them in the component descriptor,
or both. Let’s begin by exploring what this framework has to offer.
这一章是你所学SEAM的顶点。你将会结合部件、部件实例、会话、页面参数、page actions、导航规则、被管理的存储及事务来实在Open 18应用中实现几个新特性。这章末尾,用SEAM开发会变得很自然。增加你的生产生的关键是学会使用SEAM应用框架的部件模板。这些模板可以让你通过处理重复和琐碎的任务来快速开发,而让SEAM做贴身服务。你会发现这些类可以通过扩展到JAVA中得到应用,或配置到部件描述文件,或两者兼有。让我们从浏览框架开始。
10.1 A framework within a framework
As you are well aware by now, Seam is an application framework for Java EE. It provides
a container that manages components and leverages those components to tie the layers
of an enterprise Java application together. Nestled within the Seam code base lies a handful
of classes that comprise the Seam Application Framework. This “framework within
a framework” is a specialized collection of component templates that effortlessly blanket
the programming requirements of garden-variety web applications. Such tasks include
performing create, read, update, and delete (CRUD) operations on entity instances; querying
for data; and developing JSF page controllers. You may be hesitant to give this spattering
of classes much notice, but I assure you that they’ll carry you a long way.
框架中的框架
正如你现在知道的,SEAM是Java EE的应用框架。它提供一个容器来管理部件并用这些部件来绑定企业JAVA应用。在SEAM代码中嵌套带来了很多类,组成了SEAM应用框架。这个架中之架,是个部件模板的特殊集合,轻松地摆平了多变的WEB应用的编程上的需求。这些任务包括对实体实例的建立、读取、更新、或删除,请求数据,开发JSF页面控制器。你可能对这些类的分离感到犹豫,但我可以保证它们可以给你很多帮助。
NOTE
The Seam reference documentation refers to this grouping of classes as
the Seam Application Framework. The title is a potential cause of confusion,
as it resembles the name of the broader Seam framework in which it
resides. Therefore, whenever I talk about this set of classes and the functionality
they provide, I address it using the proper noun Seam Application
Framework to remain consistent with the documentation. I define it as a
framework of classes for quickly building page controllers that perform CRUD and
query operations on entities.
SEAM参考文档将这组类称为Seam应用框架。这个名字就隐含混淆。因为它近似于它所寄宿的宽泛的SEAM框架。因此,不管何时我谈论这组类及其提供的功能,我会用Seam Application Framework来与文档保持一致。我将其定义为一个框架,可以快速建立页控制器来对实体进行CRUD及查询操作。
At the end of chapter 2, you had a CRUD application in place that you could use to
impress your boss. Since then, you’ve made enhancements to the application to further
demonstrate that your investment in Seam is paying off (hopefully convincing
your boss to buy copies of this book for your coworkers). The trouble is, most of the
inner workings of those original CRUD screens, which are powered by the Seam Application
Framework, remain a mystery. You’ve learned how to manage the view-edit-save
sequence correctly using conversations and the extended persistence context. You’ll
now learn how this framework helps facilitate that use case. You’ll also discover that it
can generate status messages that keep the user informed along the way.
在第二章结束,你已有了个可以给老板看看的CRUD应用。后来又增加了很多功能。问题是这些由SEAM进行的内部工作保持着神秘。你已经学到了怎样用会话及扩展的存储上下文正确管理view-edit-save顺序,你现在会学到这个框架如何帮助这个用例。你还会发现它可以生成状态信息使用户一直了解发生的情况。
You’ll see how the framework aids in creating pages that list entities of a particular
type retrieved from the database. But it doesn’t just dump all the records at once,
which could potentially be a costly operation. Instead, it provides support for truncating
the list into pages. The component that manages the query responds to pagination
and sorting commands, and helps you develop a search filter to allow the user to
pare down the result set.
你会看到框架是怎样帮助建立页面列表从数据库中检索的特殊类型。但它不会一次取出所有记录,因为那可能会是很消耗的操作。另外,它支持将列表分为多页。管理查询的部件,负责传播和排序命令,帮助你开发一个搜索过滤器让用户提取结果集。
In this chapter, you’ll mirror the behavior and design of the screens created in
chapter 2 to incorporate a new entity into the application, Round, which represents a
round of golf. This time, you’ll build the functionality from the ground up and then
take it several steps further. This exercise allows you to become familiar with the Seam
Application Framework and shows you how to build on it. It should come as no surprise
that the cornerstone of this framework is persistence.
本章,你将为第二章增加新的输入--Round,这代表一个高尔夫加回合。这一次,你要从无到有地建立功能并继续深入。这个练习让你熟悉SEAM应用框架。这个框架的基石是存储。
10.1.1 Wrapping the persistence API
Database-oriented applications live and die by their ability to read and write relational
database tables. In the previous two chapters you’ve seen how easy it is to manage persistent
entities in a Seam application, thanks in large part to the ability of JPA and
Hibernate to transparently map objects to relational database tables and to move
them back and forth through use of a persistence manager. These object-relational
mapping (ORM) frameworks do away with verbose JDBC/SQL code sprinkled throughout
the objects in the data access layer (or worse, directly in the view).
包装实体API
面向数据库的应用生来就是为了读写关系数据库表。前两章你已看到,实体在SEAM中管理存储实体是多么容易,主要是借助了JPA和Hibernate来透明地映射到关系数据库表,来与存储管理器交互。ORM框架淘汰了数据访问层的冗长的JDBC/SQL代码(或更糟,直接通过view)。
Despite the convenience of using an ORM tool over straight JDBC, you must still
perform repetitive tasks. The general belief is that ORM operations need to be
wrapped in a data access object (DAO) to eliminate boilerplate code and remove code
duplication across projects. There’s a number of DAO frameworks that take care of
this tedious work either by generating code or by providing template classes to isolate
data operations and exceptions from the business logic. Here’s a small sampling of
these frameworks:
尽管使用ORM的会话会超载了JDBC,你仍然要操作重复的任务。总的信念是ORM操作需要被包装在数据访问对象(DAO)中,以减少模板代码并删除项目中的代码冗余。有很多DAO框架可处理这些单调的工作,或是通过生成代码或是提供模板类,来隔离数据操作及业务逻辑的异常。下面是一些这样的框架。
■ AppFuse: http://www.appfuse.org
■ Crank: http://code.google.com/p/krank
■ EL4J: http://el4j.sourceforge.net
■ OpenXava: http://www.openxava.org
DAO frameworks such as these are capable of handling the following tasks:
■ Create or obtain a reference to the persistence manager
■ Manage CRUD operations and transactions with parameterized template classes
■ Reduce casting by using generic types or generated code
■ Provide a facility to define queries declaratively and help manage the result set
DAO 框架,可处理如下任务:
建立或获得对存储管理器的参考
用参数化模板类管理CRUD操作及事务
通过使用标准的类型和代码减少类型转换
提供方法来显示地定义查询,帮助管理结果集
There’s nothing stopping you from using a data access layer in a Seam application. In
fact, for large-scale projects, I might be inclined to encourage such a design. But Seam
dispels the myth that the persistence manager must be trapped inside a DAO. Instead,
Seam proposes that the persistence manager is the DAO. But the persistence manager
isn’t a page controller—that’s where your Seam component fits in. It negotiates with
the persistence manager to perform data access operations. Not only does this design
collapse layers, it also introduces a stateful component. The data access layer has
become so ingrained in our minds that it seems we can’t just let it go and try to justify
its existence by convincing ourselves that it protects us from technology change (the
same goes for the service layer).
没有什么可以阻止你在SEAM框架使用数据访问层。事实上,大规模的项目,我倾向于鼓励这种设计。但SEAM打破了存储管理器必须位于DAO内部的说法。SEAM建议存储管理器就是DAO。但是存储管理器不是页控制器,这是SEAM部件的所在位置。其与存储管理器合作来做数据访问操作。这种设计不但瓦解了层,也引入了状态部件。数据访问层在我们思想中如此根深蒂固,以到我们感觉不能就这样没有了它并通过说服我们自己它能让我们以不变应万变来证明其存在(服务层也是这样)。
While Seam can manage the persistence context and allows it to be easily shared
among components, which you learned about in the previous chapter, the Seam
developers recognized that you still need to write a page controller. The Seam Application
Framework is a variation on the generic DAO framework, except it gets the persistence
manager and the page controller to work as a single unit rather than
introducing an additional layer of stacking. In addition, the classes in the Seam Application
Framework are aware of the state of the entities being exchanged (making it
stateful), rather than just blindly passing on operations to the persistence manager.
The framework includes two categories of persistence controllers, which you’ll learn
about in the next section: one that manages a single entity and one that manages a
result set. These controllers cover the following tasks:
SEAM可管理存储上下文,并让容易在部件间共享,这在前一章已学,SEAM的开发者认识到你仍然需要写一个页面控制器。SEAM应用框架是DAO框架的变体,只是它让存储管理器与页面控制器作为一个单独的单元工作,而不是引入一个附加的层。另外,SEAM应用框架中的类了解被交换的实体的状态(使其有状态),而不是盲目地传一个操作到存储管理器。框架包括两个存储控制器目录,你将会在下节学到:一个用于管理一个单独的实体,另一个管理一个结果集。这些控制器包含下列任务:
■ Act as a JSF form bean and action bean (page controller)
■ Create prototype instances, either to be persisted or used as part of a query
■ Assist in managing the state of the entity instance or query result set
■ Retrieve the entity instance or query result set on demand
■ Monitor the parameters to determine when the managed data needs to be
refreshed
■ Use Java 5 generics to provide type-safe checking and eliminate casting for
operations performed on the entity instance or query result set
■ Define transactional boundaries around persistence operations
■ Prepare status messages and raise events when the transaction wrapping the
operation commits successfully
作为JSF form bean 和action bean(页面控制器)
建立原型实例,或被存储或作为请求的部分
帮助管理实体状态或查询结果集
检索实体实例,或应招式查询结果
监视参数以决定什么时候数据需要被刷新
使用Java 5来提供类型安全检查以避免对于实体实例或查询结果集的操作中的类型转换
在存储操作处定义事务边界
当事务包装操作成功提交后,准备状态信息,触发事件。
Thus, the classes that comprise the Seam Application Framework don’t purposelessly
wrap the persistence API. Instead, they foster rapid development of database-oriented
applications by handling many of the auxiliary concerns required to manage persistent
entities. Let’s take a look at what classes are available and how they interact with
the persistence manager.
因此,构成SEAM应用框架的类不是无目的地包装实体API,而是促进快速的基于数据库应用的开发,通过很多用于管理存储实体的辅助概念。让我们看看什么类可用,又是怎样与存储管理器交互的。
10.1.2 The persistence controllers
The Seam Application Framework is a hierarchical set of classes, all extending from
the Controller base class. Controller contains convenience methods for accessing
the Seam contexts and component instances, interacting with the Servlet API and JSF
life cycle, logging messages, registering JSF messages, and raising events. The classes in
this hierarchy make extensive use of Java 5 generics to provide strong typing.
存储控制器
SEAM应用框架是类的层次集,所有都是基类Controller的扩展。Controller包含方便的方法来访问SEAM的上下文和部件实例。与Servlet API及Servlet API生命周期交互、日志信息、注册JSF信息及引发事件。这一层次中的类对Java 5进行扩散,提供强大的类型。
These classes are intended to be used as JavaBean components. If you wanted to
extend one to create an EJB component, you’d need to define an interface for the class
since one is not provided. Even then, the PersistenceController, which is the primary
descendent in the class hierarchy, is designed to be used with a Seam-managed
persistence manager. In particular, it provides generic access—of the Java 5 variety—to
the persistence manager as part of its class definition, shown here:
这些类的目的是用作JavaBean部件。如果你打算扩展一个来建立EJB部件,如果事先没有,你则需要为类建立一个接口。即使那样,PersistenceController,作为类层次的主要派生,被设计与Seam管理的存储管理器协同工作。特点地,对于Java 5变体们,对存储管理器,它提供通用的访问,作为它的类定义。如下:
public abstract class PersistenceController extends Controller { ... }
In this declaration, the generic type parameter T is a placeholder for the persistence
manager. Extending from the PersistenceController are three branches of classes
that facilitate interaction with the persistence manager. Each branch has an implementation
for JPA and one for Hibernate. For JPA, T is replaced with EntityManager
and for Hibernate it is replaced with Session. The controller classes in the Seam
Application Framework are summarized in table 10.1. In each of these classes, the
generic type parameter E is a placeholder for the entity class.1
在这个声明中,泛型参数T是存储管理器的占位符。从PersistenceController扩展出三个类分支,用于与存储管理器的交互。每个分支有一个JPA及一个Hibernate实现。对于JPA,T被替代为EntityManager,对于Hibernate,则为Session。SEAM应用框架的控制类,汇总于表10.1。每个这些类中,E为实体类的占位符。
The JPA implementation of this class hierarchy is diagrammed in figure 10.1.
这个类层次的JPA实现见图10.1
So what’s the benefit of wrapping the persistence manager? There are in fact
two: transaction boundaries and generics.Although the persistence manager can
control or participate in a transaction, it can’t dictate transaction boundaries. The
methods on the persistence controller, on the other hand, are decorated with
the @Transactional annotation to guarantee that the persistence operations are
nestled within an explicit transaction. In the previous chapter, you learned that Seam uses global transactions around a JSF request, so this is only a concern outside that environment. Generics allow these classes to be form-fitted to a persistence manager implementation and an entity class. Let’s
focus on the benefits of generics.
包装存储管理器有什么好处?有两个:事务边界和通用。虽然存储管理器可以控制或参加一个事务,这不声明事务的边界。另一方面,用@Transactional声明,表示是在明确的事务之中。前一章,你学了SEAM对JSF请求使用全局事务,所以这是唯一环境之外的考虑。泛型让这些类可以匹配一个存储管理器的实现及一个实体类。让我们看看泛型的好处。
A GENERIC APPROACH
It’s no secret that Seam embraces the language extensions introduced in Java 5 in
order to simplify the Java EE programming model. You’ve already seen that Seam
makes extensive use of annotations as a means of providing declarative behavior.
Seam builds on this adoption of Java 5 by using generics throughout the Seam Application
Framework. Generics help cut down on casting,2 thus removing a lot of unnecessary
clutter from your code. For example, you can adopt the EntityHome to the
Round entity using a parameterized type:
泛型方法
SEAM喜欢Java 5的语言扩展以简化Java EE开发模型。你已看到了SEAM对annotations的扩展来提供声明式行为。SEAM在SEAM应用框架中大量使用泛型。泛型减少了转型,因而减少了大量的代码。例如你可以使用一个参数化类型来应用EntityHome到Round:
EntityHome roundHome = new EntityHome();
You can then initialize a new instance of the entity without the need for a cast:
你这就可以初始化一个新的而不需要类型转换:
Course newRound = roundHome.newInstance();
The generics support is only relevant if you extend the framework classes in Java. You
also have the option of declaring your framework components entirely in XML. In that
case, the generic type parameters don’t play a role since the instances are only referenced
using the dynamically typed (or “duck-typed”) EL. Let’s consider when each is
the appropriate choice.
如果你在JAVA中扩展框架类,泛型支持是唯一相关,你也可以在XML中整体声明你的框架部件。在这种情况下,泛型参数不会起作用,因为在应用动态类型EL时,只参考实例。让我们考虑一下什么时候选择什么。
10.1.3 Two ways to play
The classes in the Seam Application Framework aren’t components themselves—
meaning they don’t bear the @Name annotation. They are component templates,
akin to the Seam-managed persistence classes covered in the previous chapter.
As you learned, one way to commission a template class as a Seam component is by
declaring and configuring it in the component descriptor, as shown here for the
roundHome component, which you’ll encounter later in this chapter:
SEAM应用框架中的类,自己并不是部件,这意味其不带@Name。他们是部件模板,同族于前一章SEAM管理的存储类。制作一个SEAM部件模板类的方法是在部件描述文件中声明或配置,如这里的roundHome部件,本章后面还会见到:
entity-class="org.open18.model.Round"/>
This component declaration falls under the built-in component namespace http://
jboss.com/products/seam/framework, prefixed as framework throughout this chapter.
Like the persistence framework classes, the application framework classes are
designed to be controlled entirely through configuration. The XML-based approach is
amazingly flexible, in large part due to the capabilities of the Seam component model
and the ubiquitous EL. When defined in this way, the component is fully capable of
preparing an entity instance to bind to the JSF form inputs and handling the form’s
actions. All of the necessary functionality is built right into the Home class.
这一部件声明使用内建的名字空间,http://jboss.com/products/seam/framework,前缀为framework,本章中会见到很多。正如存储框架类,应用框架类被设计完全通过配置来控制。这个基于XML的方法有很大的弹性,主要是借助于SEAM部件模型和随处可见的EL。当通过这一方式定义,部件完全负责准备实体实例来绑定到JSF表单录入,处理表单的actions。所有必要的功能位于Home类。
If the feature you’re looking for isn’t already covered by the framework class, the
configuration-only approach is going to come up short. Fortunately, these classes are
designed to be extended. You can extend them in Java or Groovy to build your own
custom components. This option gives you the most flexibility for all the reasons class
extension is useful. As an added bonus, you can fulfill the generic type parameters on
the parent class to get type-safe checking. Here’s the same roundHome component
defined in Java:
如果你想要的特性还没包含在框架类中,这种单靠配置的方式就不够用了。庆幸的是,这些类可以扩展。你可以在JAVA或GroovyK中建立你自己的部件。这给了你最大的弹性。一个附加的好处是你可以在父类中应用泛型参数来得到安全的类型检查。这是同样的roundHome部件在JAVA中的定义:
@Name("roundHome")
public class RoundHome extends EntityHome { ... }
Don’t feel that you have to make the decision between Java or XML up front. From the
standpoint of the rest of the application, the end result is the same, a Seam component.
You can comfortably mix the two styles in your application, or even on the same
component. In fact, the most flexible approach is to define properties in XML and the
methods on a subclass, referencing the subclass in the component descriptor. This
flexibility is the essence of the unified component model in Seam. You’re now ready
to swing away by implementing CRUD screens to manage instances of the Round entity
using a Home component.
不要觉得你必须在使用JAVA或XML中做出选择。殊途同归,结果都是SEAM部件。你可以在你的应用中混合两类型,甚至于在同一个部件上。事实上,最有弹性的方式是在XML中定义属性,在子类中定义方法,在子类中参考部件描述文件。这种弹性是SEAM统一部件模型的精华。你现在可以用Home部件去实现CRUD以管理Round实体的实例了。
10.2 Stateful CRUD using the Home component
Managed persistence has a history of being at odds with sound object-oriented design.
EJB 2 championed the use of distributed objects. As a consequence, developers
quickly resorted to using data transfer objects (DTOs) to push aggregated data over
the wire as a way to reduce network traffic. These domain objects were void of behavior.
Unfortunately, the intelligence in domain objects didn’t get restored once “lightweight”
DAO frameworks replaced EJB 2 because the same flawed architecture was
adopted. Treating domain objects as buckets for holding data, without giving them
real behavior, is an anti-pattern known as the Anemic Domain Model.3 As is the fate of
all things out of balance, a change was imminent.
使用Home部件的有状态的CRUD
被管理的存储曾是面向对象的设计的结果,EJB 2在分页式对象中获胜。结果,开发者被快速地恢复到使用数据传输对象(DTOs)来传播数据来减少网络上的数据通讯量。这些domain对象是空的行为。不幸的是,一旦轻量级的DAO框架替代了EJB2,domain对象的智能没有被保留,因为用了同样的有缺陷的框架。将domain对象看作放数据的桶,不用给他们真正的行为,这是一种反模式,名为Anemic Domain Model。一旦所有的事失衡,变化就会出现。
10.2.1 Remedying the Anemic
Domain Model
In an attempt to swing the pendulum away from the Anemic Domain Model, as illustrated in figure
10.2, some contemporary frameworks, such as Ruby on Rails, promote the use of the Active
Record design pattern as a way of making domain objects active participants in an object-oriented
design. In the Active Record pattern, the domain object is mapped directly to a database record,
just like with ORM. But this relationship is pushed further by allowing the domain object to save and retrieve itself from the database. Thus,in addition to encapsulating data, it encapsulates data access logic.
补救贫血的Domain 模型
在图10.2中的Anemic Domain Model,要摆动摆锤,一些同时代的框架如Ruby on Rails,提出了Active Record设计模式,让domain对象参与进面向对象的设计。domain对象直接映象到数据库记录,就像在用ORM。但这一关系进一步允许在数据库中保存和检索domain对象。因此,除了封装数据,也封装了数据访问逻辑。
Seam, being a progressive framework itself, supports the Active Record pattern,
right? Absolutely not. For one, the Active Record pattern has been attempted once in
J2EE and failed miserably. Entity beans from the EJB 2 era—not to be confused with JPA
entity classes in EJB 3—bear a close resemblance to the Active Record pattern since they
internalize data access logic. This interaction is particularly evident in bean-managed
persistence (BMP) entity beans, which embed SQL statements directly in the life-cycle
methods. Just like domain objects in the Active Record pattern, EJB 2 entity beans can
create, update, load, and remove the database records to which they map.
SEAM作为激进的框架,支持Active Record模式?当然不。举个例子说,Active Record pattern曾被J2EE应用,惨淡收场。整个EJB 2时代(不要与带有JPA的EJB 3混淆)很像Active Record pattern,因为内部化数据方法逻辑。这种交互是BEAN管理的存储实体bean的特殊证据。直接在生命周期方法中嵌入了SQL语句。就像Active Record pattern中的domain对象,EJB 2实体beans可以建立、更新、加载、删除其所映像的数据记录。
One of the main factors in the failure of entity beans is the hard link between the
domain object and the persistence framework. There is no separation of concerns. To
put it simply, entity beans are not POJOs. In fact, it’s difficult to implement the Active
Record pattern using POJOs. Hopefully, by now, we are in agreement that POJOs are
indicators of a sound design. They are easy to test and they are reusable. The main
reason Seam doesn’t support the Active Record pattern is because it has a better solution
based on POJOs that strikes a nice balance between the fading Anemic Domain
Model and the overeager Active Record pattern.
实体beans失败的一个主要因素是domain对象与存储框架间的硬连接。简单地说,实体beans不是POJOs。事实上,用POJOs很难实现Active Record pattern。我们同意POJO是健壮的设计的指示器。他们易于测试,并可重用。SEAM不支持Active Record pattern,主要的原因是有更好的基于POJO的方案可作为Anemic Domain Model和过于热衷的Active Record pattern的平衡。
10.2.2 Giving the domain object a Home
Entity classes are POJOs. This trait is good for reasons just mentioned, but limiting
because they can’t set transaction boundaries and can’t manage their own persistent
state (1 for POJOs, 0 for active domain models). But history has taught us that entity
classes shouldn’t handle this work anyway since it’s not a good separation of
concerns. Ideally, we want a solution that provides a competent domain model
without introducing tight coupling between the domain object and the persistence
framework.
给domain对象一个Home
实体类是一个POJOs。这一性质对前面提到的现象是个好理由,但有所限制,因为不能设置事务边界,不能管理自己的存储状态(对于 POJOs是1, 对于active domain models是0)。但历史告诉我们,实体类不能处理这些,因为没能很好地分隔概念。理想地,我们想要一个方案,提供一个部件domain模型,而不用在domain对象或存储框架间引入一个紧耦合。
INTRODUCING THE HOME COMPONENT
Seam answers this challenge by introducing the Home component (herein referred
to as a Home). A Home manages an entity instance by caching it and coordinating
CRUD operations on it with the persistence manager, all completely transparent to
the entity instance. Each Home is represented by the Home class, which extends from
PersistenceController, or any subclass of Home. As I’ve alluded to throughout this
chapter, the framework classes, such as Home, are abstract classes that are, in reality,
just component templates. They ar
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/21802202/viewspace-1027641/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/21802202/viewspace-1027641/