为什么我收到“零点错误”第二种方法中什么时候使用Junit来测试Class?

发布于 2024-12-09 02:54:59 字数 19461 浏览 1 评论 0原文

我的开发环境是: 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 downloadhttp://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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

阳光下慵懒的猫 2024-12-16 02:54:59

您的brandservicenull。查看输出

004空

编辑:检查完整来源后:

删除

<configuration>
    <parallel>methods</parallel>
    <threadCount>1</threadCount>
</configuration>

从 super-pom 中的 Surefire 配置中

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.9</version>
    <configuration>
      <parallel>methods</parallel>
      <threadCount>1</threadCount>
    </configuration>
  </plugin>

:将使其工作。看来如果测试并行执行,就会失败。

Your brandservice is null. See output

004null

EDIT: after inspecting your full sources:

remove:

<configuration>
    <parallel>methods</parallel>
    <threadCount>1</threadCount>
</configuration>

from your surefire config in super-pom:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.9</version>
    <configuration>
      <parallel>methods</parallel>
      <threadCount>1</threadCount>
    </configuration>
  </plugin>

will make it work. It seems if the tests are executed in parallel, it fails.

南城追梦 2024-12-16 02:54:59

我相信您应该将其用于 brandService 来获取它的实例:

@Autowired
@Qualifier("brandServiceImpl")
private BrandService brandService;

I believe you should use this for the brandService, to get an instance of it:

@Autowired
@Qualifier("brandServiceImpl")
private BrandService brandService;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文