一旦entity数据有所改变,将反映到数据库中。
不能确认EntityManager何时会向数据库写入更新的数据。但是这一事件肯定会发生,一般是马上,但不会晚于
EntityManager消失
;)。你可以控制触发更新数据库:
em.flush();
这将强制
EntityManager 立刻将更新写入数据库。请记住,这条语句将影响所有状态为
MANAGED的
entitie,而不是当前一个。不过,一般情况下不必这么做。
如果你想反其道而行之,也就是从数据库载入一个
entity (因为别人可能已经修改其数据),这么写:
em.refresh(entity);
怎样删除一个entity呢?很简单:
em.remove(entity);
现在,
entity的状态成为
REMOVED,表示其已经被列入删除计划。你可以用
flush()语句,让删除动作马上发生,但没必要这么干。
现在来点复杂的。当注入
EntityManager 的时候,有一个事务范围持久上下文(
Transaction Scoped Persistence Context
)。当
entitie处在
MANAGED状态时,其处在持久上下文(
persistence context
)的“容器”中。“事务范围”意味什么?首先,什么是“事务”?
EJB3
Stateful 和 Stateless beans (依同名标注辨别)的每个方法调用都包装到一个事务内。(顺便说一下,事务一旦发生
RuntimeException,即发生会滚,对数据的改变将撤销
)。因此,持久上下文(
persistence context
)将在调用方式之前建立,方式调用结束后移除。然后,持久上下文中管理的所有entity的状态成为
DETACHED。
假设在你的bean里头有两个
method。第一个是
load(), 它调用
find函数取出数据库中的一个实体。第二个是
finish(),返回一个JSF输出。调用这两个函数中间修改了实体数据。这种修改持久到数据库中吗?回答是:NO。
load() 函数结束后,
EntityManager'的持久上下文结束,它所有管理过的entity状态成为
DETACHED。一个后果是,与新entity相反-有一个ID,但他们的状态并不是
managed ,对这些
detached entities 所作的更新并不影响数据库。如果你想使一个
entity 更新数据库,需要将其重新
attach到持久上下文。在这个例子中,在
finish()方法中增加以下行:
em.merge(entity);
现在这个
entity 已经合并到
finish()方法的持久上下文中(记住,每个方法是一个事务,每个事物有自己的持久上下文),并且状态是又变为
managed。
这样做是可以的,但有两个缺点:
-需要调用merge(->多了一些代码)
-调用find()之前,如果某个entity未初始化,而你又要存取它的某些属性,将会得到
exception 错误。
有一个简单的解决方案:扩展持久上下文的生命期,这样,当调用多个事务/方法时,entity状态始终保持为
managed 。因此,我们改变
EntityManager的注入方式:
@PersistenceContext(type=PersistenceContextType.EXTENDED
private EntityManager em;
现在,
managed
entities "生活在"一个扩展持久上下文中(
Extended Persistence Context
)。
你甚至无须呼叫merge()方法,因为eitities从未被
DETACHED。你可能会问:普通事务范围(
"normal" (transaction scoped)
)持久上下文的好处是什么?它一直依附于你做的事情(小崔:什么意思?)
。扩展上下文需要更多的内存,因为即使你不需要,它也一直存在于内存。并且一旦entities被其他的bean改变(它们有自己的持久上下文),你需要显式地调用
refresh()方法(在
overviews/list页面
)。当你需要普通
EntityManager 时它就在那里,因其生命周期短,只能操作即时数据
;)
当谈及列表:为取得不止一个实体,而是一个实体集合,使用:
List<Entity> entities = em.createQuery("from Entity").getResultList();
这不是“真正”
SQL,而是类似sql的东西,称之为
EJBQL。你可以用它执行某些条件查询,排序等,如
..."from Entity where lastName=".nameToSearchFor." order by firstName"
仅使用
entity属性名称即可。关于
EJBQL 要说的太多了,但对于本篇介绍来说这已足够。
好,基本介绍到此为止。希望对你来说,在如何使用
EntityManager方面,
这一个简单易懂的介绍。
我已声明过,不能保证百分百正确。并且肯定有许多英语语法错误(对不起,我是德国人,不要打我PP噢)。欢迎斧正。
2007.4.11翻译自:
http://www.jboss.com/index.html?module=bb&op=viewtopic&t=88460