EntityManager:seam新手必读(二)

来源:互联网 发布:有孚网络待遇怎么样 编辑:程序博客网 时间:2024/04/30 14:09
    一旦entity数据有所改变,将反映到数据库中。不能确认EntityManager何时会向数据库写入更新的数据。但是这一事件肯定会发生,一般是马上,但不会晚于EntityManager消失;)。你可以控制触发更新数据库:

em.flush();    

     这将强制EntityManager 立刻将更新写入数据库。请记住,这条语句将影响所有状态为MANAGEDentitie,而不是当前一个。不过,一般情况下不必这么做。
    如果你想反其道而行之,也就是从数据库载入一个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
原创粉丝点击