为什么我收到“零点错误”第二种方法中什么时候使用Junit来测试Class?
我的开发环境是: netbeas7.01 + mysql5 + spring3 + struts2 + jpa2(hibernate3.6;
当我重构一个旧项目时,我遇到了一些麻烦:运行项目时出现随机“空点”错误,请问有什么办法吗?哪位给我一些建议,谢谢。
完整项目下载:http:// www.oschina.net/action/code/download?code=6526&id=10445
构建日志:
Running com.itcast.service.product.BrandServiceTest
001com.itcast.service.product.BrandServiceImpl@10d0eae
entityManager=save()===Shared EntityManager proxy for target factory [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@120b2da]
002922defe1-38d4-48f5-8fa5-b43027f897d9
2011-10-11 18:02:50 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans.xml]
2011-10-11 18:02:51 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.GenericApplicationContext@1e893df: startup date [Tue Oct 11 18:02:51 CST 2011]; root of context hierarchy
2011-10-11 18:02:51 org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
信息: Loading properties file from class path resource [jdbc.properties]
2011-10-11 18:02:51 org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
信息: Bean 'dataSource' of type [class org.apache.commons.dbcp.BasicDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2011-10-11 18:02:51 org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
信息: Bean 'org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver#145c859' of type [class org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2011-10-11 18:02:51 org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean createNativeEntityManagerFactory
信息: Building JPA container EntityManagerFactory for persistence unit 'itcast'
2011-10-11 18:02:54 org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
信息: Bean 'entityManagerFactory' of type [class org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2011-10-11 18:02:54 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1ffc686: defining beans [brandServiceImpl,typeServiceImpl,uploadFileServiceImpl,/control/product/allbrandsfinder,/control/product/alltypesfinder,/control/product/branddeleter,/control/product/brandfinder,/control/product/brandsaver,/control/product/brandupdater,/control/product/typedeleter,/control/product/typefinder,/control/product/typesaver,/control/product/typeupdater,/control/upload/uploadfilesaver,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0,dataSource,org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0,entityManagerFactory,org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor#0,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor]; root of factory hierarchy
003测试Find()方法!
004null
Tests run: 2, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 8.868 sec <<< FAILURE!
Results :
Tests in error:
testfind(com.itcast.service.product.BrandServiceTest)
Tests run: 7, Failures: 0, Errors: 1, Skipped: 0
------------------------------------------------------------------------
BUILD FAILURE
------------------------------------------------------------------------
Total time: 10.939s
Finished at: Tue Oct 11 18:02:56 CST 2011
Final Memory: 4M/254M
错误日志:
-------------------------------------------------------------------------------
Test set: com.itcast.service.product.BrandServiceTest
-------------------------------------------------------------------------------
Tests run: 2, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 8.868 sec <<< FAILURE!
testfind(com.itcast.service.product.BrandServiceTest) Time elapsed: 0.008 sec <<< ERROR!
java.lang.NullPointerException
at com.itcast.service.product.BrandServiceTest.testfind(BrandServiceTest.java:59)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.apache.maven.surefire.junitcore.ConfigurableParallelComputer$AsynchronousRunner$1.call(ConfigurableParallelComputer.java:186)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
junit 类:
/*
* Copyright 2011 待到道成日,纵横天地间.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.itcast.service.product;
import com.itcast.model.product.Brand;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
*
* @author Kang.Cunhua
*/
@ContextConfiguration(locations = {"classpath:beans.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class BrandServiceTest {
private static final Logger logger = Logger.getLogger(BrandServiceTest.class.getName());
@Resource(name = "brandServiceImpl")
private BrandService brandService;//= new BrandServiceImpl();
@Test
public void testSave() {
Brand brand = new Brand("远阳瑜伽", "/image/brand/2011/10/04/yuanyangyujia.png");
System.err.println("001" + brandService);
brandService.save(brand);
System.err.println("002" + brand.getCode());
}
@Test
public void testfind() {
System.out.println("003" + "测试Find()方法!");
System.err.println("004" + brandService);
Brand brand = (Brand) brandService.find(Brand.class, "55fba033-b4a7-4d61-89c0-2564b020731c");
System.err.println("005" + brand.getCode());
logger.log(Level.INFO, "获取id为\"55fba033-b4a7-4d61-89c0-2564b020731c\"的记录! {0}", brand);
}
}
一些确切的代码关于测试类 *BrandServiceImpl.java*
/*
* Copyright 2011 待到道成日,纵横天地间.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.itcast.service.product;
import com.itcast.model.product.Brand;
import java.util.UUID;
import com.itcast.service.dao.DaoSupport;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
*
* @author Kang.Cunhua
*/
@Service //标注为Spring的Servicebean,供自动扫描机制加载该bean,就不用再beans.xml中声明了
@Transactional
public class BrandServiceImpl extends DaoSupport implements BrandService {
public BrandServiceImpl() {
}
@Override
public void save(Object entity) {
((Brand) entity).setCode(UUID.randomUUID().toString());
super.save(entity);
}
}
DaoSupport.java
package com.itcast.service.dao;
import com.itcast.model.QueryResult;
import java.util.LinkedHashMap;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
*
* @author kang.cunhua
*/
@Transactional // 后面的方法都会具有默认的事务行为
public abstract class DaoSupport implements Dao {
/**
*
*/
@PersistenceContext
protected EntityManager em; // 允许子类访问,不用再在子类中注入
@Override
public void save(Object entity) {
//System.out.println("entityManager====" + em + "caller========" + Reflection.getCallerClass(2));
em.persist(entity);
}
@Override
public void update(Object entity) {
em.merge(entity);
}
@Override
public <T> void delete(Class<T> entityClass, Object entityid) {
delete(entityClass, new Object[]{entityid});
}
@Override
public <T> void delete(Class<T> entityClass, Object[] entityids) {
for (Object id : entityids) {
em.remove(em.getReference(entityClass, id));
}
}
@Override
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
public <T> T find(Class<T> entityClass, Object entityId) {
//System.out.println("entityManager====" + em);
return em.find(entityClass, entityId);
}
@Override
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
public <T> QueryResult<T> getScrollData(Class<T> entityClass, int firstindex,
int maxresult, String wherejpql, Object[] queryParams, LinkedHashMap<String, String> orderby) {
QueryResult qr = new QueryResult<T>();
String entityname = getEntityName(entityClass);
Query query = em.createQuery("select o from " + entityname + " o " + (wherejpql == null ? "" : "where " + wherejpql) + buildOrderby(orderby));
setQueryParams(query, queryParams);
if (firstindex != -1 && maxresult != -1) {
query.setFirstResult(firstindex);
query.setMaxResults(maxresult);
//这两句也可以简写为:query.setFirstResult(firstindex).setMaxResults(maxresult);
}
qr.setResultlist(query.getResultList());
query = em.createQuery("select count(o) from " + entityname + " o " + (wherejpql == null ? "" : "where " + wherejpql));
setQueryParams(query, queryParams);
qr.setTotalrecord((Long) query.getSingleResult());
return qr;
}
/**
*
* @param <T>
* @param entityClass
* @param firstindex
* @param maxresult
* @param orderby
* @return
*/
@Override
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
public <T> QueryResult<T> getScrollData(Class<T> entityClass, int firstindex, int maxresult, LinkedHashMap<String, String> orderby) {
return getScrollData(entityClass, firstindex, maxresult, null, null, orderby);
}
/**
*
* @param <T>
* @param entityClass
* @param firstindex
* @param maxresult
* @param wherejpql
* @param queryParams
* @return
*/
@Override
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
public <T> QueryResult<T> getScrollData(Class<T> entityClass, int firstindex, int maxresult, String wherejpql, Object[] queryParams) {
return getScrollData(entityClass, firstindex, maxresult, wherejpql, queryParams, null);
}
/**
*
* @param <T>
* @param entityClass
* @param firstindex
* @param maxresult
* @return
*/
@Override
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
public <T> QueryResult<T> getScrollData(Class<T> entityClass, int firstindex, int maxresult) {
return getScrollData(entityClass, firstindex, maxresult, null, null, null);
}
/**
*
* @param <T>
* @param entityClass
* @return
*/
@Override
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
public <T> QueryResult<T> getScrollData(Class<T> entityClass) {
return getScrollData(entityClass, -1, -1);
}
/**
*
* @param query
* @param queryParams
*/
protected void setQueryParams(Query query, Object[] queryParams) {
if (queryParams != null && queryParams.length > 0) {
for (int i = 0; i < queryParams.length; i++) {
query.setParameter(i + 1, queryParams[i]);
}
}
}
/**
* 组装order by 语句
* @param orderby
* @return
*/
protected String buildOrderby(LinkedHashMap<String, String> orderby) {
StringBuilder orderbyql = new StringBuilder();
if (orderby != null && orderby.size() > 0) {
orderbyql.append(" order by ");
// order by o.key desc,o.key2 asc
for (String key : orderby.keySet()) {
orderbyql.append("o.").append(key).append(" ").append(orderby.get(key)).append(",");
}
orderbyql.deleteCharAt(orderbyql.length() - 1);
}
return orderbyql.toString();
}
/**
* 利用反射技术得到要传递到分页方法中的实体类的名字,简单名字还是自定义名字
* @param <T>
* @param entityClass
* @return
*/
protected <T> String getEntityName(Class<T> entityClass) {
String entityname = entityClass.getSimpleName();
Entity entity = entityClass.getAnnotation(Entity.class);
if (entity.name() != null && !"".equals(entity.name())) {
entityname = entity.name();
}
return entityname;
}
}
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
Document : beans.xml
Created on : 2010年12月13日, 下午5:07
Author : kang.cunhua
Description: Spring3.05+JPA(Hibernate3.6)集成.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="com.itcast"/>
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${driverClassName}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}"/>
<!-- 连接池启动时的初始值 -->
<property name="initialSize" value="${initialSize}" />
<!-- 连接池的最大值 -->
<property name="maxActive" value="${maxActive}"/>
<!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->
<property name="maxIdle" value="${maxIdle}"/>
<!-- 最小空闲值,当空闲的连接数少于阀值时,连接池就会去申请一些连接,以免洪峰来时来不及申请 -->
<property name="minIdle" value="${minIdle}" />
</bean>
<!-- This will ensure that hibernate or jpa exceptions are automatically translated into
Spring's generic DataAccessException hierarchy for those classes annotated with Repository
For example see PersonDaoJpa-->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<!-- 类工厂由spring管理 -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/><!-- 注入数据源bean到实体管理工厂bean -->
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
<property name="loadTimeWeaver"><!-- 运行时植入 -->
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>
<!-- bean post-processor for JPA annotations -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<!-- 事务由spring管理 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/><!-- 注入实体管理工厂bean到事务管理bean -->
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/><!-- 事务声明方式是注解 -->
</beans>
My develop environment is: netbeas7.01 + mysql5 + spring3 + struts2 + jpa2(hibernate3.6;
When I Refactoring a old project,I got some trouble:there is a random “null point” error when I run the project,could any one give me some suggestion,thanks.
full project download:http://www.oschina.net/action/code/download?code=6526&id=10445
build log:
Running com.itcast.service.product.BrandServiceTest
001com.itcast.service.product.BrandServiceImpl@10d0eae
entityManager=save()===Shared EntityManager proxy for target factory [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@120b2da]
002922defe1-38d4-48f5-8fa5-b43027f897d9
2011-10-11 18:02:50 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans.xml]
2011-10-11 18:02:51 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.GenericApplicationContext@1e893df: startup date [Tue Oct 11 18:02:51 CST 2011]; root of context hierarchy
2011-10-11 18:02:51 org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
信息: Loading properties file from class path resource [jdbc.properties]
2011-10-11 18:02:51 org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
信息: Bean 'dataSource' of type [class org.apache.commons.dbcp.BasicDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2011-10-11 18:02:51 org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
信息: Bean 'org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver#145c859' of type [class org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2011-10-11 18:02:51 org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean createNativeEntityManagerFactory
信息: Building JPA container EntityManagerFactory for persistence unit 'itcast'
2011-10-11 18:02:54 org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization
信息: Bean 'entityManagerFactory' of type [class org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2011-10-11 18:02:54 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1ffc686: defining beans [brandServiceImpl,typeServiceImpl,uploadFileServiceImpl,/control/product/allbrandsfinder,/control/product/alltypesfinder,/control/product/branddeleter,/control/product/brandfinder,/control/product/brandsaver,/control/product/brandupdater,/control/product/typedeleter,/control/product/typefinder,/control/product/typesaver,/control/product/typeupdater,/control/upload/uploadfilesaver,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0,dataSource,org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0,entityManagerFactory,org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor#0,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor]; root of factory hierarchy
003测试Find()方法!
004null
Tests run: 2, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 8.868 sec <<< FAILURE!
Results :
Tests in error:
testfind(com.itcast.service.product.BrandServiceTest)
Tests run: 7, Failures: 0, Errors: 1, Skipped: 0
------------------------------------------------------------------------
BUILD FAILURE
------------------------------------------------------------------------
Total time: 10.939s
Finished at: Tue Oct 11 18:02:56 CST 2011
Final Memory: 4M/254M
error log:
-------------------------------------------------------------------------------
Test set: com.itcast.service.product.BrandServiceTest
-------------------------------------------------------------------------------
Tests run: 2, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 8.868 sec <<< FAILURE!
testfind(com.itcast.service.product.BrandServiceTest) Time elapsed: 0.008 sec <<< ERROR!
java.lang.NullPointerException
at com.itcast.service.product.BrandServiceTest.testfind(BrandServiceTest.java:59)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.apache.maven.surefire.junitcore.ConfigurableParallelComputer$AsynchronousRunner$1.call(ConfigurableParallelComputer.java:186)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
junit class:
/*
* Copyright 2011 待到道成日,纵横天地间.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.itcast.service.product;
import com.itcast.model.product.Brand;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
*
* @author Kang.Cunhua
*/
@ContextConfiguration(locations = {"classpath:beans.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class BrandServiceTest {
private static final Logger logger = Logger.getLogger(BrandServiceTest.class.getName());
@Resource(name = "brandServiceImpl")
private BrandService brandService;//= new BrandServiceImpl();
@Test
public void testSave() {
Brand brand = new Brand("远阳瑜伽", "/image/brand/2011/10/04/yuanyangyujia.png");
System.err.println("001" + brandService);
brandService.save(brand);
System.err.println("002" + brand.getCode());
}
@Test
public void testfind() {
System.out.println("003" + "测试Find()方法!");
System.err.println("004" + brandService);
Brand brand = (Brand) brandService.find(Brand.class, "55fba033-b4a7-4d61-89c0-2564b020731c");
System.err.println("005" + brand.getCode());
logger.log(Level.INFO, "获取id为\"55fba033-b4a7-4d61-89c0-2564b020731c\"的记录! {0}", brand);
}
}
some exact code about testclass
*BrandServiceImpl.java*
/*
* Copyright 2011 待到道成日,纵横天地间.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.itcast.service.product;
import com.itcast.model.product.Brand;
import java.util.UUID;
import com.itcast.service.dao.DaoSupport;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
*
* @author Kang.Cunhua
*/
@Service //标注为Spring的Servicebean,供自动扫描机制加载该bean,就不用再beans.xml中声明了
@Transactional
public class BrandServiceImpl extends DaoSupport implements BrandService {
public BrandServiceImpl() {
}
@Override
public void save(Object entity) {
((Brand) entity).setCode(UUID.randomUUID().toString());
super.save(entity);
}
}
DaoSupport.java
package com.itcast.service.dao;
import com.itcast.model.QueryResult;
import java.util.LinkedHashMap;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
*
* @author kang.cunhua
*/
@Transactional // 后面的方法都会具有默认的事务行为
public abstract class DaoSupport implements Dao {
/**
*
*/
@PersistenceContext
protected EntityManager em; // 允许子类访问,不用再在子类中注入
@Override
public void save(Object entity) {
//System.out.println("entityManager====" + em + "caller========" + Reflection.getCallerClass(2));
em.persist(entity);
}
@Override
public void update(Object entity) {
em.merge(entity);
}
@Override
public <T> void delete(Class<T> entityClass, Object entityid) {
delete(entityClass, new Object[]{entityid});
}
@Override
public <T> void delete(Class<T> entityClass, Object[] entityids) {
for (Object id : entityids) {
em.remove(em.getReference(entityClass, id));
}
}
@Override
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
public <T> T find(Class<T> entityClass, Object entityId) {
//System.out.println("entityManager====" + em);
return em.find(entityClass, entityId);
}
@Override
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
public <T> QueryResult<T> getScrollData(Class<T> entityClass, int firstindex,
int maxresult, String wherejpql, Object[] queryParams, LinkedHashMap<String, String> orderby) {
QueryResult qr = new QueryResult<T>();
String entityname = getEntityName(entityClass);
Query query = em.createQuery("select o from " + entityname + " o " + (wherejpql == null ? "" : "where " + wherejpql) + buildOrderby(orderby));
setQueryParams(query, queryParams);
if (firstindex != -1 && maxresult != -1) {
query.setFirstResult(firstindex);
query.setMaxResults(maxresult);
//这两句也可以简写为:query.setFirstResult(firstindex).setMaxResults(maxresult);
}
qr.setResultlist(query.getResultList());
query = em.createQuery("select count(o) from " + entityname + " o " + (wherejpql == null ? "" : "where " + wherejpql));
setQueryParams(query, queryParams);
qr.setTotalrecord((Long) query.getSingleResult());
return qr;
}
/**
*
* @param <T>
* @param entityClass
* @param firstindex
* @param maxresult
* @param orderby
* @return
*/
@Override
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
public <T> QueryResult<T> getScrollData(Class<T> entityClass, int firstindex, int maxresult, LinkedHashMap<String, String> orderby) {
return getScrollData(entityClass, firstindex, maxresult, null, null, orderby);
}
/**
*
* @param <T>
* @param entityClass
* @param firstindex
* @param maxresult
* @param wherejpql
* @param queryParams
* @return
*/
@Override
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
public <T> QueryResult<T> getScrollData(Class<T> entityClass, int firstindex, int maxresult, String wherejpql, Object[] queryParams) {
return getScrollData(entityClass, firstindex, maxresult, wherejpql, queryParams, null);
}
/**
*
* @param <T>
* @param entityClass
* @param firstindex
* @param maxresult
* @return
*/
@Override
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
public <T> QueryResult<T> getScrollData(Class<T> entityClass, int firstindex, int maxresult) {
return getScrollData(entityClass, firstindex, maxresult, null, null, null);
}
/**
*
* @param <T>
* @param entityClass
* @return
*/
@Override
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
public <T> QueryResult<T> getScrollData(Class<T> entityClass) {
return getScrollData(entityClass, -1, -1);
}
/**
*
* @param query
* @param queryParams
*/
protected void setQueryParams(Query query, Object[] queryParams) {
if (queryParams != null && queryParams.length > 0) {
for (int i = 0; i < queryParams.length; i++) {
query.setParameter(i + 1, queryParams[i]);
}
}
}
/**
* 组装order by 语句
* @param orderby
* @return
*/
protected String buildOrderby(LinkedHashMap<String, String> orderby) {
StringBuilder orderbyql = new StringBuilder();
if (orderby != null && orderby.size() > 0) {
orderbyql.append(" order by ");
// order by o.key desc,o.key2 asc
for (String key : orderby.keySet()) {
orderbyql.append("o.").append(key).append(" ").append(orderby.get(key)).append(",");
}
orderbyql.deleteCharAt(orderbyql.length() - 1);
}
return orderbyql.toString();
}
/**
* 利用反射技术得到要传递到分页方法中的实体类的名字,简单名字还是自定义名字
* @param <T>
* @param entityClass
* @return
*/
protected <T> String getEntityName(Class<T> entityClass) {
String entityname = entityClass.getSimpleName();
Entity entity = entityClass.getAnnotation(Entity.class);
if (entity.name() != null && !"".equals(entity.name())) {
entityname = entity.name();
}
return entityname;
}
}
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
Document : beans.xml
Created on : 2010年12月13日, 下午5:07
Author : kang.cunhua
Description: Spring3.05+JPA(Hibernate3.6)集成.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="com.itcast"/>
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${driverClassName}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}"/>
<!-- 连接池启动时的初始值 -->
<property name="initialSize" value="${initialSize}" />
<!-- 连接池的最大值 -->
<property name="maxActive" value="${maxActive}"/>
<!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->
<property name="maxIdle" value="${maxIdle}"/>
<!-- 最小空闲值,当空闲的连接数少于阀值时,连接池就会去申请一些连接,以免洪峰来时来不及申请 -->
<property name="minIdle" value="${minIdle}" />
</bean>
<!-- This will ensure that hibernate or jpa exceptions are automatically translated into
Spring's generic DataAccessException hierarchy for those classes annotated with Repository
For example see PersonDaoJpa-->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<!-- 类工厂由spring管理 -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/><!-- 注入数据源bean到实体管理工厂bean -->
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
<property name="loadTimeWeaver"><!-- 运行时植入 -->
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>
<!-- bean post-processor for JPA annotations -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<!-- 事务由spring管理 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/><!-- 注入实体管理工厂bean到事务管理bean -->
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/><!-- 事务声明方式是注解 -->
</beans>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的
brandservice
为null
。查看输出编辑:检查完整来源后:
删除
从 super-pom 中的 Surefire 配置中
:将使其工作。看来如果测试并行执行,就会失败。
Your
brandservice
isnull
. See outputEDIT: after inspecting your full sources:
remove:
from your surefire config in super-pom:
will make it work. It seems if the tests are executed in parallel, it fails.
我相信您应该将其用于
brandService
来获取它的实例:I believe you should use this for the
brandService
, to get an instance of it: