[SEAM] 热帖:seam里面另人无奈的bug
darwinwen
2009-05-11
XML中的<begin-conversation join="true" flush-mode="manual"/>
等同于 @Begin(join = true,flushMode = FlushModeType.MANUAL) 意义是一样的,都是开启一个长会话,将flushMode设置为MANUAL, 将flushMode设置为MANUAL的原因,下面假如你是继承EntityHome或是HibernateEntityHome类,我以EntityHome源代码update方法为例说明. /** * Base class for Home objects of JPA entities. * * @author Gavin King * */ public class EntityHome<E> extends Home<EntityManager, E> { @Transactional public String update() { joinTransaction(); getEntityManager().flush(); updatedMessage(); raiseAfterTransactionSuccessEvent(); return "updated"; } } 注意@Transactional事务标记以及getEntityManager().flush(),如果标记为@Begin(join = true),将flushMode将默认为AUTO,意味着你对在会话期间对实体做的任何修改,持入化上下文将直接进行脏检测,发现实体修改Seam容器将会自动调用getEntityManager().flush()方法清空缓存,提交到数据库,所以才会产生你现在的问题.将flushMode设置为MANUAL将是告诉Seam由你自己来调用getEntityManager().flush()方法,也就是你想要的做完验证之后合法的数据再提交到数据库.当然这些问题还有可能取决于你Entity的equals()和hashCode()方法的重写,这是Hibernate与JPA的知识,这里不作过多的讨论. 而改成这样之后 就不会出现以上的问题了,可是页面中的值却跟着改变了,我刷新也没用,直到我关闭页面 重新运行页面,它的值才会显示成最初未改动的值。。。而在整个过程当中,DB的数据是一直没变的(这是我想要的),可是我怎么样才能让页面的值不会出现那种“假象”?? 这个问题,相信你已经理解Spring与Seam最大的区别,一个是无状态的,一个是有状态的,以及Seam的双向注入@In @Out, 当你注释@Beject标志,或是在XML写入一个begin-conversation节点,都代表是开启一个长会话,直到你标记@End或是在XML 写入<env-conversation>标记,才会结束当前这个会话,在会话期间你对@Name("")标记的实体进行的修改,Seam都会返回到Seam管理的上下文中,说白点就是把修改的后的对象重新复制一份到Seam上下文容器中,Seam容器透明的管理. 解决办法,下面的给你个例子参考.你可以使用在你的实体中使用增加一个@PostLoad标记方法,来将name的初始值保存到nameInitial临时变量中. @Transient private String nameInitial; @NotNull @Column(name = "ROLE_NAME", length = 50) @Length(max = 50) private String name; @PostLoad public void afterLoad() { this.nameInitial = this.name; } 使用@PostLoad方法,这个是代表在实体装入时把name的初始值传给nameInitial, 这样你就可以保存你修改后name的初始值. 以上仅供参考,个人的理解. |
|
无双Rama
2009-05-12
to darwinwen :
解决办法,下面的给你个例子参考.你可以使用在你的实体中使用增加一个@PostLoad标记方法,来将name的初始值保存到nameInitial临时变量中. @Transient private String nameInitial; @NotNull @Column(name = "ROLE_NAME", length = 50) @Length(max = 50) private String name; @PostLoad public void afterLoad() { this.nameInitial = this.name; } 使用@PostLoad方法,这个是代表在实体装入时把name的初始值传给nameInitial, 这样你就可以保存你修改后name的初始值. 这个方法可以,但是如果我的页面要修改的属性有很多个时,实体就写得很繁琐了。呵呵~~~~ 非常感谢你的回复!! |