SEAM IN ACTION 第10章

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为实体类的占位符。

clip_image001.png

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声明,表示是在明确的事务之中。前一章,你学了SEAMJSF请求使用全局事务,所以这是唯一环境之外的考虑。泛型让这些类可以匹配一个存储管理器的实现及一个实体类。让我们看看泛型的好处。

clip_image002.png

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的扩展来提供声明式行为。SEAMSEAM应用框架中大量使用泛型。泛型减少了转型,因而减少了大量的代码。例如你可以使用一个参数化类型来应用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.

不要觉得你必须在使用JAVAXML中做出选择。殊途同归,结果都是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对象。因此,除了封装数据,也封装了数据访问逻辑。

clip_image003.png

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/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值