2008-05-28
把我的SEAM开发中碰到的问题全贴出来(比较零散,涉及到很多方面的问题)
关键字: seam开发手记
可能有些内容其他人不知道我在说什么
组件中被作为事件处理的方法一定要在接口中声明其方法,再在XXXBean中实现其方法,不然会报错:找不到方法绑定。
如果使用默认的XHTML格式的页面,那页面导航可能要在pages.xml文件里面配置,不然会导致注入失败,绑定的值无法被传输,具体原因还在查明中
如果想用JSF默认的页面导航就使用JSP格式的文件并把默认的文件后缀改成jsp而不是xhtml
在QL语句中所涉及到的表名和字段名都要使用实体名和实体的getter方法的名字(field名),字段中出现字符串的字段要加上单引号
@Out注出的时候,对象不能够被设定为null,可以把相应的属性设置为空字符串
@In(create=true)如果在上下文中找不到要注入的实例,就自动创建一个,如果不设置自动创建,就可能要报错.一定要保证注入的值不能为空.或者可以指定@In(require=false)表示可以为空(NULL),但在组件的方法中千万不要拿它来进行操作,否则就会出错,因为它可以为空,所以一个没有被创建对象是不能用来操作的
注意,在对列进行命名的时候要注意千万不要和MYSQL的保留字段有冲突,无论大小写,比如MYSQL保留字段为READ,在给列命名的时候read也不可以。
貌似有操作才会有注出
用于页面导航的结果首字母最好不要大写,全部小写!如果是大字,则只会停留在原来的页面而不会导航到你所希望的页面.
conversation上下文要配合工作流使用,不然会出现不可思议注入问题,而且一个conversation没有工作流的支持,它的生命周期也只是一个请求而以~~
Yes but you are finding the item and then removing it. As you aren't inside a transaction, once the item has been found, it will now be detached. When you delete it, the exception occurs. If you fix the transaction attributes it should work.
如果在有状态组件中要删除一个表中的实体,可能会出现上述情况,但如果把持久化上下文改为扩展的持久化上下文就不会有事了
不知道是一发现还是一什么,说说吧:
表中被选中的实体会注入,我再将它注出到上下文中,用几个edit框来绑定它的属性,只要对这个属性进行修改,再提交一下,修改过的资料就会自动更新到数据库了.
为什么在setter中加上@NotNull后会发生异常呢?还搞不清楚
可能是因为标记的是那个被丢到上下文的实体而不是我要注出的那个实体,而那个实体又没有被设置值,还是空的,如果我一提交,自然会出事了.
如果不指定主键自动生成,则在添加商品的时候会产生错误
在实体的操作中最好加入事务了,不然很多麻烦的.
不过现在事情有了新的进展,只要把实体改成对话的范围,再用merge把它拉入持久化上下文中受管,它立即自动更新到数据库!!不用再调用persis
定义一个简单的安全规则
首先要在component.xml中把验证方法指定好.这个方法必须是要返回一个boolean值,以确定验证是否成功,在验证成功的分支里要用addRole()方法来添加一个被许可的成员,它的参数是一个字符串,比如说是'admin'
然后在XXX.page.xml中定义登陆页面的导航方向
Identity是Seam的一个内置组件,在登陆页面上直接使用它的属性来和输入控件绑定,在验证的时候再用Identity来提取用户名和密码.Identity的identity.loggedIn方法是判断用户是否登入了
在组件中添加@Restrict("#{s:hasRole('admin')}")注解,中的参数表明了有没有'admin'这个角色,有就可以调用被限制了的方法,没有就无法访问.
JSF页面的中文解决方式
<?xml version="1.0" encoding="gbk"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:rich="http://richfaces.org/rich">
<head>
<title>SEAM</title>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
</head>
<body>
中文解决方式
</body>
</html>
要记住,无法初始化组件和无法创建组件是有区别的,为什么无法初始化,自己找找原因
在persistence.xml中hbm2ddl的value="validate"设成none可以不要它去验证mapping的正确性,如果表设计得不够好,验证就会出事.
首先数据源是提供给持久化单元引用的,在SEAM里面.
在一个持久化单元中指定两个数据源,可以这样
<persistence-unit name="GTHP">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/GTHPDatasource</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>
<property name="hibernate.hbm2ddl.auto" value="none"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="jboss.entity.manager.factory.jndi.name" value="java:/GTHPEntityManagerFactory"/>
<property name="hibernate.default_catalog" value="gth_account"/>
<property name="hibernate.default_schema" value="dbo"/>
</properties>
</persistence-unit>
<persistence-unit name="GTHP2">
<jta-data-source>java:/MSSQL</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>
<property name="hibernate.hbm2ddl.auto" value="none"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="jboss.entity.manager.factory.jndi.name" value="java:/GTHPEntityManagerFactory"/>
<property name="hibernate.default_catalog" value="gth_account"/>
<property name="hibernate.default_schema" value="dbo"/>
</properties>
</persistence-unit>
之后持久化管理器只要指定一个要引用哪个持久化单元的名字,就可以引用不同的数据源了.
Jboss中EJB使用时,同时调用两个数据源的时候出现问题
同时调用两个数据源程序会报错[com.arjuna.ats.internal.jta.transaction.arjunacore.lastResource.disallow] Adding multiple last resources is disallowed. Current resource is org.jboss.resource.connectionmanager.TxConnectionManager$LocalXAResource@d006a7
需要在jboss 配置文件jbossjta-properties.xml中增加<property name="com.arjuna.ats.jta.allowMultipleLastResources" value="true"/> 这个配置后应用正常
默认情况下,有状态组件的上下文范围是conversation,而这个范围的上下文的生命周期又只是一个请求,所以在有注入操作的情况下,不要用默认的上下文范围,这样会导致注入的内容会和组件随同销毁,这样绑定的方法就无法调用了,所以想要这些切正常工作,就要显式指定上下文范围为SESSION
更改JBOSS访问路径
在使用ear进行发布 在ear中配置文件中 把 context-root的值设置一下
例如
<module>
<web>
<web-uri>aaa.war</web-uri>
<context-root>/</context-root>
</web>
</module>
用文件上传的组件时,对于文件的保存,是不可以直接使用item.getData()的.必须用输入流来读取文件成字节,再用输入流把它写成文件.
组件中被作为事件处理的方法一定要在接口中声明其方法,再在XXXBean中实现其方法,不然会报错:找不到方法绑定。
如果使用默认的XHTML格式的页面,那页面导航可能要在pages.xml文件里面配置,不然会导致注入失败,绑定的值无法被传输,具体原因还在查明中
如果想用JSF默认的页面导航就使用JSP格式的文件并把默认的文件后缀改成jsp而不是xhtml
在QL语句中所涉及到的表名和字段名都要使用实体名和实体的getter方法的名字(field名),字段中出现字符串的字段要加上单引号
@Out注出的时候,对象不能够被设定为null,可以把相应的属性设置为空字符串
@In(create=true)如果在上下文中找不到要注入的实例,就自动创建一个,如果不设置自动创建,就可能要报错.一定要保证注入的值不能为空.或者可以指定@In(require=false)表示可以为空(NULL),但在组件的方法中千万不要拿它来进行操作,否则就会出错,因为它可以为空,所以一个没有被创建对象是不能用来操作的
注意,在对列进行命名的时候要注意千万不要和MYSQL的保留字段有冲突,无论大小写,比如MYSQL保留字段为READ,在给列命名的时候read也不可以。
貌似有操作才会有注出
用于页面导航的结果首字母最好不要大写,全部小写!如果是大字,则只会停留在原来的页面而不会导航到你所希望的页面.
conversation上下文要配合工作流使用,不然会出现不可思议注入问题,而且一个conversation没有工作流的支持,它的生命周期也只是一个请求而以~~
Yes but you are finding the item and then removing it. As you aren't inside a transaction, once the item has been found, it will now be detached. When you delete it, the exception occurs. If you fix the transaction attributes it should work.
如果在有状态组件中要删除一个表中的实体,可能会出现上述情况,但如果把持久化上下文改为扩展的持久化上下文就不会有事了
不知道是一发现还是一什么,说说吧:
表中被选中的实体会注入,我再将它注出到上下文中,用几个edit框来绑定它的属性,只要对这个属性进行修改,再提交一下,修改过的资料就会自动更新到数据库了.
为什么在setter中加上@NotNull后会发生异常呢?还搞不清楚
可能是因为标记的是那个被丢到上下文的实体而不是我要注出的那个实体,而那个实体又没有被设置值,还是空的,如果我一提交,自然会出事了.
如果不指定主键自动生成,则在添加商品的时候会产生错误
在实体的操作中最好加入事务了,不然很多麻烦的.
不过现在事情有了新的进展,只要把实体改成对话的范围,再用merge把它拉入持久化上下文中受管,它立即自动更新到数据库!!不用再调用persis
定义一个简单的安全规则
首先要在component.xml中把验证方法指定好.这个方法必须是要返回一个boolean值,以确定验证是否成功,在验证成功的分支里要用addRole()方法来添加一个被许可的成员,它的参数是一个字符串,比如说是'admin'
然后在XXX.page.xml中定义登陆页面的导航方向
Identity是Seam的一个内置组件,在登陆页面上直接使用它的属性来和输入控件绑定,在验证的时候再用Identity来提取用户名和密码.Identity的identity.loggedIn方法是判断用户是否登入了
在组件中添加@Restrict("#{s:hasRole('admin')}")注解,中的参数表明了有没有'admin'这个角色,有就可以调用被限制了的方法,没有就无法访问.
JSF页面的中文解决方式
<?xml version="1.0" encoding="gbk"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:rich="http://richfaces.org/rich">
<head>
<title>SEAM</title>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
</head>
<body>
中文解决方式
</body>
</html>
要记住,无法初始化组件和无法创建组件是有区别的,为什么无法初始化,自己找找原因
在persistence.xml中hbm2ddl的value="validate"设成none可以不要它去验证mapping的正确性,如果表设计得不够好,验证就会出事.
首先数据源是提供给持久化单元引用的,在SEAM里面.
在一个持久化单元中指定两个数据源,可以这样
<persistence-unit name="GTHP">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/GTHPDatasource</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>
<property name="hibernate.hbm2ddl.auto" value="none"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="jboss.entity.manager.factory.jndi.name" value="java:/GTHPEntityManagerFactory"/>
<property name="hibernate.default_catalog" value="gth_account"/>
<property name="hibernate.default_schema" value="dbo"/>
</properties>
</persistence-unit>
<persistence-unit name="GTHP2">
<jta-data-source>java:/MSSQL</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>
<property name="hibernate.hbm2ddl.auto" value="none"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="jboss.entity.manager.factory.jndi.name" value="java:/GTHPEntityManagerFactory"/>
<property name="hibernate.default_catalog" value="gth_account"/>
<property name="hibernate.default_schema" value="dbo"/>
</properties>
</persistence-unit>
之后持久化管理器只要指定一个要引用哪个持久化单元的名字,就可以引用不同的数据源了.
Jboss中EJB使用时,同时调用两个数据源的时候出现问题
同时调用两个数据源程序会报错[com.arjuna.ats.internal.jta.transaction.arjunacore.lastResource.disallow] Adding multiple last resources is disallowed. Current resource is org.jboss.resource.connectionmanager.TxConnectionManager$LocalXAResource@d006a7
需要在jboss 配置文件jbossjta-properties.xml中增加<property name="com.arjuna.ats.jta.allowMultipleLastResources" value="true"/> 这个配置后应用正常
默认情况下,有状态组件的上下文范围是conversation,而这个范围的上下文的生命周期又只是一个请求,所以在有注入操作的情况下,不要用默认的上下文范围,这样会导致注入的内容会和组件随同销毁,这样绑定的方法就无法调用了,所以想要这些切正常工作,就要显式指定上下文范围为SESSION
更改JBOSS访问路径
在使用ear进行发布 在ear中配置文件中 把 context-root的值设置一下
例如
<module>
<web>
<web-uri>aaa.war</web-uri>
<context-root>/</context-root>
</web>
</module>
用文件上传的组件时,对于文件的保存,是不可以直接使用item.getData()的.必须用输入流来读取文件成字节,再用输入流把它写成文件.


评论
说的对,conversation跟工作流没有关系,完全可以单独使用对话,我们现在所有的table都绑定到conversation范围。
实体bean默认就是对话范围的,不需要在明确定义。