[SEAM] 讨论几个seam开发细节问题

pf_miles 2008-04-30
问题1)一个最最普通的SLSB处理请求的情况:
在页面上:
<h:inputText value="#{newCreditType.name}" id="creditTypeName" />


在SLSB中:
@In(required = false, create = true)
	@Out
	private CreditType newCreditType;

运行的时候显然页面上会报“newCreditType不存在”的错误,那么这个时候我就在SLSB里面加了这么一个factory方法:
@Factory("newCreditType")
public void createNewCreditType(){
    this.newCreditType=new CreditType();
}

这样就算解决了问题,不过我不能接受!因为createNewCreditType这个方法非常愚蠢,就是构造了一个空白的对象而已,它让我的代码更加啰嗦。我认为这个对象应该交由页面来构造,然后传给SLSB。也肯定有办法解决,只是我没想到;我想听听大家是怎么做的,我现在粗略想到的就是用一个converter构造一个对象传到后端,不知道可不可行,有没有更好的办法?(肯定是有的,只是我不知道而已)

问题2)EntityBean中,被标记为@Transient的属性在merge或persist的时候不可见:
假如有如下代码:
@Entity
public class Something{
	@Id
	@GeneratedValue
	private long id;

	private String detailLob;

	@Transient
	private Map<String, String> detailMap;

	@PrePersist
	@PreUpdate
	public void serializeDetail(){
		// serialize this.detailMap to this.detailLob
		// ......
	}
	// ......
}

可以看到,我原本的想法是在这个对象被插入数据库或更新到数据库之前,将那个Transient的对象序列化到一个非Transient的属性中,下次查询这个对象的时候还可以反序列化出来;可是,我发现在serializeDetail方法中却拿不到这个Map对象了,也就是说,不管之前Map有没有值,在merge或persist的时候这个Map属性就是null!这让我很伤心,我只好在调用merge或persist之前就将这个Map序列化好,当然,也用不上那两个@PrePersist和@PreUpdate标签了...
不知道有没有解决办法,使它能在插入或更新之前拿到这个Transient属性,否则,我敢肯定@PrePersist和@PreUpdate标签的应用价值会大打折扣。

问题3)在APPLICATION scope里面的的东西,经过某个Session Bean修改后反注回去会不会产生线程问题?

也许这个问题有点傻,不过既然问出来了,那也就谈一谈吧:
@Stateless
@Name("SomeAction")
@Local
public class SomeActionImpl implements SomeAction, Serializable{
	@In("something")
	@Out(value="something", scope=ScopeType.APPLICATION)
	private Something something;
	public void someAction(){
		// change sth. of this.something
	}
	// ......
}

如上,something是一个APPLICATION scope里面的东西,被注入到这个SomeActionImpl里面之后调用someAction方法对这个注入的something对象做了一点更改,调用完毕之后反注回APPLICATION scope中去。我想,如果这个action如果调用很频繁的话肯定是会出现并发问题的,那么是否APPLICATION scope里面就最好不要放可更改的值呢?这个问题大家怎么看?
atusoft 2008-04-30
第一个问题里newCreditType不是一个component吗,是的话就应该由页面生成啊?如果加了@name的话
pf_miles 2008-04-30
atusoft 写道
第一个问题里newCreditType不是一个component吗,是的话就应该由页面生成啊?如果加了@name的话

你这么一说我又打开debug.htm仔细研究了一下,貌似creditType.component和creditType这个上下文变量不是同一个东西;我开始也想到你所说的直接在CreditType这个Entity上直接加上@Name,但我担心其他没有用到creditType变量的页面访问也默认生成一个Conversation范围的creditType变量,所以没那么做;请问会是这样吗?是的话我觉得创造的上下文变量是不是太多了呢?
不好意思,我感觉帮助手册里面的东西实在有点少,而且没怎么讲清楚...
atusoft 2008-05-01
没有用到的话怎么会生成呢。除非你在页面中调用#{creditType.xxx},而系统中又没有creditType实例的话,才会生成一个。 如果你是说平常的访问这一页时,creditType不需要显示的话,那用rendered或者s:freagment好了
5day 2008-05-04
问题一:
1)factory的方法比较灵活,你可以作些@name不能作的初始化操作。
2)不过一般用@name
3)实在不想用component就直接用#{xxxxxx},这个xxxxxxx也是可以@In的。
newCreditType.name=xxxxxx;就ok了。
yourenyouyu2008 2008-05-05
问题一:
@Factory不在@Name定义的类中是不能被使用的吧?
pf_miles 2008-05-05
yourenyouyu2008 写道
问题一:
@Factory不在@Name定义的类中是不能被使用的吧?

这个是可以的,只能去试试你才知道...手册里没说;而且中文资料也少;
现在忙,等有时间了我再去翻看一下那堆英文seam书,好歹也得总结点东西出来..现在感觉seam开发,特别是刚接触不久的,会遇到很多“疑难杂症”,很多还必须自己去摸索出来,对于时间比较紧的,而自己又不熟seam的,选择seam容易扇到自己嘴巴...玩弄手册里那些例子真的比较容易,但目前来看,那些例子还没有提供足够的细节...遇到疑难杂症还是很头痛...
我原以为seam对我来说可以像用appFuse配好的SSH一样几下搞定,但现在看来简直太不一样了,seam确实理念很新,虽然声称上手简单但在真正了解一些细节之前还是很难做一些真正的开发的,我觉得不能用传统框架的使用经验去度量它啊...
fireflyc 2008-05-24
第一个问题是代码的问题
用这样的方法调用:

@Name("test")
class Test{
@In(required = false, create = true)  
      @Out
      private CreditType newCreditTy


#{test.newCreditTy.name}

第二个问题我想是这样的。
当我们注解@Transient时seam会修改字节码,把我们的那个属性却掉,然后采用JPA保存经过修改的对象。具体的可能要看一下seam的代码。解决办法我暂时没有想到。
第三个问题比较容易回答。
Servlet本身在容器中就是多线程方式进行处理的。所以底层上就是多线程的。
也就是说每当一个请求发送过来都会创建一个SomeActionImpl来进行服务。(具体的生命周期还是SomeActionImpl的注解在起作用。在struts1.2中是只实例化一次Action,所以Action是线程不安全的,Struts2的线程安全是因为每次请求都会一个干净的对象。而seam的实现是要根据注解来判断是否实例化新的对象的。)
pf_miles 2008-05-25
fireflyc 写道
第一个问题是代码的问题
用这样的方法调用:

@Name("test")
class Test{
@In(required = false, create = true)  
      @Out
      private CreditType newCreditTy


#{test.newCreditTy.name}

第二个问题我想是这样的。
当我们注解@Transient时seam会修改字节码,把我们的那个属性却掉,然后采用JPA保存经过修改的对象。具体的可能要看一下seam的代码。解决办法我暂时没有想到。
第三个问题比较容易回答。
Servlet本身在容器中就是多线程方式进行处理的。所以底层上就是多线程的。
也就是说每当一个请求发送过来都会创建一个SomeActionImpl来进行服务。(具体的生命周期还是SomeActionImpl的注解在起作用。在struts1.2中是只实例化一次Action,所以Action是线程不安全的,Struts2的线程安全是因为每次请求都会一个干净的对象。而seam的实现是要根据注解来判断是否实例化新的对象的。)

第一个问题终于明白了,多谢指点!

第三个问题我也知道servlet是多线程服务,我只是想问问在修改application context里的对象之后,再反注(outject)回application context中会不会有诸如脏读和重复写入等等多线程问题;现在我也明白这个问题了,seam的文档里讲contexts的时候说的很清楚了,跟传统的application作用域一样,呵呵,这个问题确实问得比较傻。
多谢了!
pf_miles 2008-05-27
fireflyc 写道
第一个问题是代码的问题
用这样的方法调用:

@Name("test")
class Test{
@In(required = false, create = true)  
      @Out
      private CreditType newCreditTy


#{test.newCreditTy.name}


对于第一个问题我试了试更多情况:如果这个"Test"类是一个POJO,那么相上述这样使用是没问题的;但如果是一个SessionBean,那就必须把newCreditType的getter和setter方法添加到SessionBean的接口上,不然会报propertieNotFound的错误;这样虽然能运行,但还是很不爽,getter和setter方法怎么好意思加在SessionBean的接口上呢?想问问有没有什么解决方法?再次感谢!
Global site tag (gtag.js) - Google Analytics