(转)我的APPFUSE2.0.1开发过程的问题记录和解决办法
http://www.pben.cn/read.htm?action=topic&id=8a8181871a519f9c011a54b337e9055d&bid=33&fcpage=1&fcaction=index&tagId=0
1。怎样使每次测试时不删除数据库中表结构?
解答:将pom.xml配置中的如下代码屏蔽掉。
<!--
plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>hibernate3-maven-plugin</artifactId>
<version>2.0-alpha-2</version>
<configuration>
<components>
<component>
<name>hbm2ddl</name>
<implementation>
annotationconfiguration
</implementation>
</component>
</components>
<componentProperties>
<drop>true</drop>
<jdk5>true</jdk5>
<propertyfile>
target/classes/jdbc.properties
</propertyfile>
<skip>${maven.test.skip}</skip>
</componentProperties>
</configuration>
<executions>
<execution>
<phase>process-test-resources</phase>
<goals>
<goal>hbm2ddl</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>${jdbc.groupId}</groupId>
<artifactId>${jdbc.artifactId}</artifactId>
<version>${jdbc.version}</version>
</dependency>
</dependencies>
</plugin -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>hibernate3-maven-plugin</artifactId>
<version>2.0-alpha-2</version>
<configuration>
<components>
<component>
<name>hbm2ddl</name>
<implementation>
annotationconfiguration
</implementation>
</component>
</components>
<componentProperties>
<drop>true</drop>
<jdk5>true</jdk5>
<propertyfile>
target/classes/jdbc.properties
</propertyfile>
<skip>${maven.test.skip}</skip>
</componentProperties>
</configuration>
<executions>
<execution>
<phase>process-test-resources</phase>
<goals>
<goal>hbm2ddl</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>${jdbc.groupId}</groupId>
<artifactId>${jdbc.artifactId}</artifactId>
<version>${jdbc.version}</version>
</dependency>
</dependencies>
</plugin -->
2。怎样使用外部配置变量?
解答:a。在pom.xml配置文件中加入占位符
如: <!-- FTP settings -->
<
ftp
.url
>
135.224.82.4
</
ftp.url
>
< ftp .username > ls </ ftp.username >
< ftp .password > FdbEgT+7 </ ftp.password >
< ftp .path > /data/jyf/0000/SRC/ </ ftp.path >
< ftp .username > ls </ ftp.username >
< ftp .password > FdbEgT+7 </ ftp.password >
< ftp .path > /data/jyf/0000/SRC/ </ ftp.path >
b。在resources目录下新建文本文件ftp.properties
ftp.url
=
${ftp.url}
ftp.username = ${ftp.username}
ftp.password = ${ftp.password}
ftp.path = ${ftp.path}
ftp.username = ${ftp.username}
ftp.password = ${ftp.password}
ftp.path = ${ftp.path}
c。在引用的applicationContext文件节点propertyConfigurer中添加<value>classpath:ftp.properties</value>
d。这时就可以直接使用占位符了
如: <!--FTP Server-START-->
<bean id="myFTP" class="com.xjgzinfo.app.util.MyFTP"
lazy-init="true" destroy-method="destroy">
<property name="server" value="${ftp.url}" />
<property name="user" value="${ftp.username}" />
<property name="password" value="${ftp.password}" />
<property name="path" value="${ftp.path}" />
</bean>
<!--FTP Server-END-->
3。测试Dao时报如下错误该怎么解决?
Unsatisfied dependency expressed through bean property 'interfaceDataDefineDao': Set this property value or disable dependency checking for this bean
解答:以下列出3种解决方法,优先选择方法1。
解决方法1:测试初始化没有自动加载webapp/WEB-INF/applicationContext.xml文件,把该文件复制到target\classes\目录下即可。
解决方法2:修改build path将src/main/webapp的out put folder修改成default output folder(实际是target/classes),此方法实际是将webapp里的文件都复制到target/classes里,使得测试过程可以访问到applicationContext.xml文件。
解决方法3:复制target/test-classes/的WEB-INF文件夹到target/classes目录下,使得集成测试可以访问该目录下的文件。
4。怎样解决测试报“Embedded error: java.sql.SQLException: ORA-01401: 插入的值对于列过大”错误?
解答:检查hmb2ddl生成的数据表字段的实际类型及大小,再跟test/resources/samples-data.xml里对应的表的测试数据比较,检查是否跟实际数据库表中数据类型不匹配。有时appfuse自动产生的测试数据过大造成的,修改测试数据即可。
5。怎样使用本地mvean_proxy?
解答:本地运行java -jar maven-proxy-standalone-0.2-app.jar maven-proxy.properties,然后在pom.xml库中修改配置
<
repositories
>
< repository >
< id > central </ id >
< name > xjgzinfo Central Repository </ name >
< url > http://135.224.80.12:9999/repository </ url >
< snapshots >
< enabled > true </ enabled >
</ snapshots >
< releases >
< enabled > true </ enabled >
</ releases >
</ repository >
< repository >
< id > appfuse </ id >
< url > http://static.appfuse.org/repository </ url >
</ repository >
< repository >
< id > Maven2 </ id >
< url > http://repo1.maven.org/maven2 </ url >
</ repository >
<!-- Needed for Facelets -->
< repository >
< id > java.net </ id >
< url > http://download.java.net/maven/1/ </ url >
< layout > legacy </ layout >
</ repository >
</ repositories >
< pluginRepositories >
< pluginRepository >
< id > central </ id >
< name > xjgzinfo Central Repository </ name >
< url > http://135.224.80.12:9999/repository </ url >
</ pluginRepository >
< pluginRepository >
< id > appfuse </ id >
< url > http://static.appfuse.org/repository </ url >
</ pluginRepository >
</ pluginRepositories >
< repository >
< id > central </ id >
< name > xjgzinfo Central Repository </ name >
< url > http://135.224.80.12:9999/repository </ url >
< snapshots >
< enabled > true </ enabled >
</ snapshots >
< releases >
< enabled > true </ enabled >
</ releases >
</ repository >
< repository >
< id > appfuse </ id >
< url > http://static.appfuse.org/repository </ url >
</ repository >
< repository >
< id > Maven2 </ id >
< url > http://repo1.maven.org/maven2 </ url >
</ repository >
<!-- Needed for Facelets -->
< repository >
< id > java.net </ id >
< url > http://download.java.net/maven/1/ </ url >
< layout > legacy </ layout >
</ repository >
</ repositories >
< pluginRepositories >
< pluginRepository >
< id > central </ id >
< name > xjgzinfo Central Repository </ name >
< url > http://135.224.80.12:9999/repository </ url >
</ pluginRepository >
< pluginRepository >
< id > appfuse </ id >
< url > http://static.appfuse.org/repository </ url >
</ pluginRepository >
</ pluginRepositories >
6。使用JSF时怎样向菜单上添加子菜单,及关联事件处理代码?
解答:a.首先在ApplicationResources.properties资源配置文件中添加变量
例如:# -- auditReport day tast page --
auditReportDayTask.execute=AuditReport Task Run
auditReportDayTask.executed=AuditReport has been runned successfully.
# -- AuditReport-END
b.向AuditReportForm.java文件中添加事件响应代码
例如: public String auditDay() {
auditReportManager.autoAuditDay();
addMessage("auditReportDayTask.executed");
return "mainMenu";
}
c.在mainMenu.xhtml文件中添加commandLink
例如:<h:commandLink value="#{text['auditReportDayTask.execute']}" action="#{auditReportForm.auditDay}"/>
7。怎样向Mvean中installing 3rd party JARs?
解答:To install a JAR in the local repository use the following command:
mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> \
-DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>
例如:mvn install:install-file -Dfile=quartz-1.6.0.jar -DgroupId=quartz -DartifactId=quartz -Dversion=1.6.0 -Dpackaging=jar
8。怎样在pom.xml中配置3rd party JARs,使得mvn integration-test集成测试后打包成war文件?
解答:向dependency中添加依赖,通过第7步的安装就可以从本地库中引用第三方jar文件了。
例如:
<
dependency
>
< groupId > quartz </ groupId >
< artifactId > quartz </ artifactId >
< version > ${quartz.version} </ version >
< scope > compile </ scope >
</ dependency >
< quartz .version > 1.6.0 </ quartz.version >
< groupId > quartz </ groupId >
< artifactId > quartz </ artifactId >
< version > ${quartz.version} </ version >
< scope > compile </ scope >
</ dependency >
< quartz .version > 1.6.0 </ quartz.version >
9。怎样使用Ioc在Spring框架中使用bean自动管理对象?
解答:a.编写需要被Spring管理的类,如MyFTP.java;
b.在applicationContext.xml或applicationContext-resources.xml中配置bean;
如:
<!--
FTP Server-START
-->
< bean id ="myFTP" class ="com.xjgzinfo.app.util.MyFTP"
lazy-init ="true" destroy-method ="destroy" >
< property name ="server" value ="${ftp.url}" />
< property name ="user" value ="${ftp.username}" />
< property name ="password" value ="${ftp.password}" />
< property name ="localResource" value ="${ftp.localPath}" />
< property name ="remotePath" value ="${ftp.remotePath}" />
</ bean >
<!-- FTP Server-END -->
10。怎样使用由Spring自动管理的bean对象?
解答:a.在需要使用该bean的类中添加该属性对象,如NamedSQLParser xmlParser = null;
并添加相应的get和set方法;
b.在applicationContext.xml中配置该bean;
<!-- AuditReportManager-START -->
< bean id ="auditReportManager"
class ="com.xjgzinfo.app.service.impl.AuditReportManagerImpl" >
< constructor-arg ref ="auditReportDao" />
< property name ="myftp" ref ="myFTP" />
< property name ="xmlParser" ref ="namedSQLParser" />
</ bean >
<!-- AuditReportManager-END -->
< bean id ="myFTP" class ="com.xjgzinfo.app.util.MyFTP"
lazy-init ="true" destroy-method ="destroy" >
< property name ="server" value ="${ftp.url}" />
< property name ="user" value ="${ftp.username}" />
< property name ="password" value ="${ftp.password}" />
< property name ="localResource" value ="${ftp.localPath}" />
< property name ="remotePath" value ="${ftp.remotePath}" />
</ bean >
<!-- FTP Server-END -->
10。怎样使用由Spring自动管理的bean对象?
解答:a.在需要使用该bean的类中添加该属性对象,如NamedSQLParser xmlParser = null;
并添加相应的get和set方法;
b.在applicationContext.xml中配置该bean;
<!-- AuditReportManager-START -->
< bean id ="auditReportManager"
class ="com.xjgzinfo.app.service.impl.AuditReportManagerImpl" >
< constructor-arg ref ="auditReportDao" />
< property name ="myftp" ref ="myFTP" />
< property name ="xmlParser" ref ="namedSQLParser" />
</ bean >
<!-- AuditReportManager-END -->
c.在AuditReportManagerImpl.java类中直接使用xmlParser属性,该对象已经在auditReportManager由Spring装载时实例化了。
11。在使用Spring框架时怎样通过application context访问资源?
解答:a.通过虚拟路径来存取.如果我们的资源文件位于CLASSPATH下,我们就可以通过这种方法来获取资 源文件,获取代码如下:
ApplicationContext context = new FileSystemXmlApplicationContext("src/org/spring/test/applicationContext.xml");
Resource resource = context.getResource("classpath:message.properties");
这里需要注意的是classpath:是spring约定的URL虚拟路径.
b.或通过实际路径来存取:
获取代码如下:
ApplicationContext context = new FileSystemXmlApplicationContext("src/org/spring/test/applicationContext.xml");
Resource resource = context.getResource("file:D:/JProject/SpringTest/src/message.properties");
c.或通过相对路径来存取:
获取方法:
ApplicationContext context = new FileSystemXmlApplicationContext("src/org/spring/test/applicationContext.xml");
Resource resource = context.getResource("src/message.properties");
12。怎样把Resource作为属性来配置?
解答:a.首先创建待配置bean的java源文件AuditReportManagerImpl.java,该文件中要有Resource类型属性,如UrlResource,ClassPathResource,FileSystemResource,ServletContextResource,InputStreamResource,ByteArrayResource其中一种资源变量。例如private ClassPathResource xmlResource;
b.然后在applicationContext.xml或applicationContext-resources.xml配置文件中配置该bean;
如:
<!--NamedSQLParser Server-START-->
<bean id="namedSQLParser" class="com.xjgzinfo.app.util.NamedSQLParser">
<property name="xmlResource" value="classpath:nativeSQL.hbm.xml"/>
</bean>
<!--NamedSQLParser Server-END-->
c.通过web.xml中配置的监听,如
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
该监听会在web容器启动时对该web应用实例化ApplicationContext对象,通过a,b两步的配置ApplicationContext对象会实例化该资源,并获取classpath下的nativeSQL.hbm.xml资源文件返回给AuditReportManagerImpl.java中的Resource类型属性,在本例中我的xmlResource属性就可以在AuditReportManagerImpl中直接使用了。
13。怎样使用命名查询?
解答:a.在src/main/resources/目录下建立命名查询的配置文件,如:nativeSQL.hbm.xml
<?
xml version="1.0" encoding="utf-8"
?>
<! DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<!--
This is the native SQL entity queries config document.
You must list all columns of the entity.The primary key must unique.
You will get a list with entity object.
-->
< hibernate-mapping >
< sql-query name ="1000PARA01" >
< return alias ="auditReport"
class ="com.xjgzinfo.app.model.AuditReport" >
</ return >
<![CDATA[
select min(rownum) as {auditReport.id},
NULL as {auditReport.acct_date},
NULL as {auditReport.acct_month},
NULL as {auditReport.audit_name},
product_type as {auditReport.field1},
state as {auditReport.field2},
count(1) as {auditReport.field3},
NULL as {auditReport.field4},
NULL as {auditReport.field5},
NULL as {auditReport.field6},
NULL as {auditReport.field7},
NULL as {auditReport.field8},
NULL as {auditReport.field9},
NULL as {auditReport.field10},
NULL as {auditReport.field11},
NULL as {auditReport.field12},
NULL as {auditReport.field13},
NULL as {auditReport.field14},
NULL as {auditReport.field15},
NULL as {auditReport.field16},
NULL as {auditReport.field17},
NULL as {auditReport.field18},
NULL as {auditReport.region_name},
NULL as {auditReport.partition_id_region}
from ls6_para.product_t@ysdb
group by product_type, state
]]>
</ sql-query >
</ hibernate-mapping >
<! DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<!--
This is the native SQL entity queries config document.
You must list all columns of the entity.The primary key must unique.
You will get a list with entity object.
-->
< hibernate-mapping >
< sql-query name ="1000PARA01" >
< return alias ="auditReport"
class ="com.xjgzinfo.app.model.AuditReport" >
</ return >
<![CDATA[
select min(rownum) as {auditReport.id},
NULL as {auditReport.acct_date},
NULL as {auditReport.acct_month},
NULL as {auditReport.audit_name},
product_type as {auditReport.field1},
state as {auditReport.field2},
count(1) as {auditReport.field3},
NULL as {auditReport.field4},
NULL as {auditReport.field5},
NULL as {auditReport.field6},
NULL as {auditReport.field7},
NULL as {auditReport.field8},
NULL as {auditReport.field9},
NULL as {auditReport.field10},
NULL as {auditReport.field11},
NULL as {auditReport.field12},
NULL as {auditReport.field13},
NULL as {auditReport.field14},
NULL as {auditReport.field15},
NULL as {auditReport.field16},
NULL as {auditReport.field17},
NULL as {auditReport.field18},
NULL as {auditReport.region_name},
NULL as {auditReport.partition_id_region}
from ls6_para.product_t@ysdb
group by product_type, state
]]>
</ sql-query >
</ hibernate-mapping >
b.在src/main/resources/hibernate.cfg.xml文件中添加资源文件
<mapping resource="nativeSQL.hbm.xml" />
c.在DaoHibernate实现java文件类中就可以通过调用super.getHibernateTemplate().findByNamedQuery(queryName);方法执行命名查询了。而且super.getHibernateTemplate().findByNamedQueryAndNamedParam()方法支持带参数的sql语句。
d.注意!命名查询语句必须给出完整的对应与AuditReport对象属性的字段,否则会报“nested exception is java.sql.SQLException: 列名无效”的错误。当AuditReport对象设定关键字时,{auditReport.id}的值不能为NULL,否则会报“java.lang.NullPointerException”的错误;{auditReport.id}的值要唯一才能正确返回结果,否则返回的List<AuditReport>中的AuditReport对象都一样。
14。怎样使用Dom4j读取XML文件?
解答:a。导入如下包:
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
b。采用如下语句片段读取XML节点:
private List namedSQL;// 命名查询列表,用于存放解析后得到的命名查询
private
ClassPathResource xmlResource;
//
待解析的XML文件名
try {
// 采用Dom4j解析nativeSQL.hbm.xml文件
List errors = new ArrayList();
Document doc;
XMLHelper xmlHelper = new XMLHelper();
doc = xmlHelper.createSAXReader(this.xmlResource.getFilename(),
errors, XMLHelper.DEFAULT_DTD_RESOLVER).read(
this.xmlResource.getInputStream());
final Element root = doc.getRootElement();// 取得root跟节点
// 遍历XML树
for (Iterator i = root.elementIterator("sql-query"); i.hasNext();) {
Element sqlQuery = (Element) i.next();
this.namedSQL.add(sqlQuery.attributeValue("name"));// 获取该节点的name属性
}
if (errors.size() != 0) {
throw new MappingException("invalid configuration",
(Throwable) errors.get(0));
}
} catch (DocumentException ex) {
ex.getStackTrace();
} catch (IOException ex) {
ex.getStackTrace();
}
try {
// 采用Dom4j解析nativeSQL.hbm.xml文件
List errors = new ArrayList();
Document doc;
XMLHelper xmlHelper = new XMLHelper();
doc = xmlHelper.createSAXReader(this.xmlResource.getFilename(),
errors, XMLHelper.DEFAULT_DTD_RESOLVER).read(
this.xmlResource.getInputStream());
final Element root = doc.getRootElement();// 取得root跟节点
// 遍历XML树
for (Iterator i = root.elementIterator("sql-query"); i.hasNext();) {
Element sqlQuery = (Element) i.next();
this.namedSQL.add(sqlQuery.attributeValue("name"));// 获取该节点的name属性
}
if (errors.size() != 0) {
throw new MappingException("invalid configuration",
(Throwable) errors.get(0));
}
} catch (DocumentException ex) {
ex.getStackTrace();
} catch (IOException ex) {
ex.getStackTrace();
}
c。对以上语句的解释,xmlResource是资源文件对应的变量,对应的XML文件就是以上13问答用到的nativeSQL.hbm.xml文件。该资源使用方法见以上12解答。XMLHelper.DEFAULT_DTD_RESOLVER是对XML文件中DOCTYPE标记进行解析的解析器,该解析器碰到http://hibernate.sourceforge.net描述资源时首先会到hibernate-3.2.5.ga.jar文件的org/hibernate路径下寻找指定的dtd文件,如果找不到才会到http://hibernate.sourceforge.net网站读取该dtd文件。具体使用方法可以参照hibernate-3.2.5.ga.jar/org/hibernate/util/下的XMLHelper.class、ConfigHelper.class和DTDEntityResolver.class
15。测试时报“ Error executing database operation: CLEAN_INSERT
Embedded error: Listener refused the connection with the following error:
ORA-12518, TNS:listener could not hand off client connection
The Connection des.c.r.i.p.tor used by the client was:
localhost:1521:Ora9i”怎么处理?
解答:提示这个错误的原因是由于当前配置的Ora9i数据库不能连接。检查网络或开启数据库实例。
16。使用Oracle作数据库时,PL/SQL Developer工具连接数据库正常,但是测试时报“[INFO] Error executing database operation: CLEAN_INSERT
Embedded error: my_table_name_t”,是怎么回事?
解答:这是因为在appfuse中数据库配置方案名要大写,如下配置:
<!--
Database settings
-->
< dbunit .dataTypeFactoryName >
org.dbunit.ext.oracle.OracleDataTypeFactory
</ dbunit.dataTypeFactoryName >
< dbunit .schema > HR </ dbunit.schema > <!-- Make sure to capitalize the schema name 这里已经清楚地告诉我们方案名要大写 -->
< dbunit .operation.type > CLEAN_INSERT </ dbunit.operation.type >
< hibernate .dialect >
org.hibernate.dialect.Oracle9iDialect
</ hibernate.dialect >
< hibernate .show_sql > true </ hibernate.show_sql >
< jdbc .groupId > com.oracle </ jdbc.groupId >
< jdbc .artifactId > ojdbc14 </ jdbc.artifactId >
< jdbc .version > 10.2.0.2.0 </ jdbc.version >
< jdbc .driverClassName >
oracle.jdbc.OracleDriver
</ jdbc.driverClassName >
< jdbc .url >
<![CDATA[ jdbc:oracle:thin:@localhost:1521:Ora9i ]]>
</ jdbc.url >
< jdbc .username > hr </ jdbc.username >
< jdbc .password > hr </ jdbc.password >
< dbunit .dataTypeFactoryName >
org.dbunit.ext.oracle.OracleDataTypeFactory
</ dbunit.dataTypeFactoryName >
< dbunit .schema > HR </ dbunit.schema > <!-- Make sure to capitalize the schema name 这里已经清楚地告诉我们方案名要大写 -->
< dbunit .operation.type > CLEAN_INSERT </ dbunit.operation.type >
< hibernate .dialect >
org.hibernate.dialect.Oracle9iDialect
</ hibernate.dialect >
< hibernate .show_sql > true </ hibernate.show_sql >
< jdbc .groupId > com.oracle </ jdbc.groupId >
< jdbc .artifactId > ojdbc14 </ jdbc.artifactId >
< jdbc .version > 10.2.0.2.0 </ jdbc.version >
< jdbc .driverClassName >
oracle.jdbc.OracleDriver
</ jdbc.driverClassName >
< jdbc .url >
<![CDATA[ jdbc:oracle:thin:@localhost:1521:Ora9i ]]>
</ jdbc.url >
< jdbc .username > hr </ jdbc.username >
< jdbc .password > hr </ jdbc.password >
17。采用Hibernate3时对于大批量保存操作该怎么处理?
解答:对于大批量的数据入库操作,要定量刷新缓存,采用super.getSession().flush(),Hibernate会自动生成原始SQL语句,将内存中的数据持久化到数据库中。否则会导致内存溢出。采用如下语句:
/** */
/**
* 批量插入VO
*
* @param objs
* 批量插入transient态的VO结果集
*/
public List batchInsert(List < AuditReport > objs) {
log.debug("Inserting into table by List<AuditReport>.");
try {
for (int i = 0; i < objs.size(); i++) {
super.getHibernateTemplate().save(objs.get(i));
if (i % 20 == 0) {
super.getSession().flush();
super.getSession().clear();
}
}
return objs;
} catch (DataAccessException dae) {
log.error("insert into table by collection fail.", dae);
throw dae;
} catch (RuntimeException re) {
log.error("insert into table by collection fail.", re);
throw re;
}
}
* 批量插入VO
*
* @param objs
* 批量插入transient态的VO结果集
*/
public List batchInsert(List < AuditReport > objs) {
log.debug("Inserting into table by List<AuditReport>.");
try {
for (int i = 0; i < objs.size(); i++) {
super.getHibernateTemplate().save(objs.get(i));
if (i % 20 == 0) {
super.getSession().flush();
super.getSession().clear();
}
}
return objs;
} catch (DataAccessException dae) {
log.error("insert into table by collection fail.", dae);
throw dae;
} catch (RuntimeException re) {
log.error("insert into table by collection fail.", re);
throw re;
}
}