简体   繁体   中英

JUnit returns error creating bean with name 'sessionFactory' defined in URL

I am a newbie to JUnit. To experiment it, I would like to test a repository class of Spring. It has only one method that is used to retrieve rows based on provided id but I am receiving an exception. I've found out one way to solve the issue is to add a context class but I am not sure if that helps, if that does, not sure how to do it. Another question is do I need to run the project when I want to run the testcases?!!

Exception

 java.lang.IllegalStateException: Failed to load ApplicationContext
            at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:94)
            at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
            at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(
            .........
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Table1RepositoryImpl': 
Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not 
autowire field: private org.hibernate.SessionFactory com.myproject.repository.Table1RepositoryImpl.sessionFactory; nested 
exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in URL 
[file:WebContent/WEB-INF/my-servlet.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: 
javax.persistence.OneToMany.orphanRemoval()Z
        at 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(
        ....
    Caused by: org.springframework.beans.factory.BeanCreationException: 
Could not autowire field: private org.hibernate.SessionFactory 
com.myproject.repository.Table1RepositoryImpl.sessionFactory; nested 
exception is org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'sessionFactory' defined in URL [file:WebContent/WEB-INF/my-servlet.xml]: Invocation of init method 
failed; nested exception is java.lang.NoSuchMethodError:
javax.persistence.OneToMany.orphanRemoval()Z
    ....
    Caused by: org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'sessionFactory' defined in URL 
[file:WebContent/WEB-INF/my-servlet.xml]: Invocation of init method 
failed; nested exception is java.lang.NoSuchMethodError: 
javax.persistence.OneToMany.orphanRemoval()Z
        ......
    Caused by: java.lang.NoSuchMethodError: javax.persistence.OneToMany.orphanRemoval()Z
        at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:2021)
        at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:895)
        at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:728)
        at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3625)
        at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3579)
        at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1381)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1786)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1870)
        at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:372)
        at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:454)
        at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:439)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1625)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1562)
        ... 53 more

JUnit Test Case

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"file:WebContent/WEB-INF/my-servlet.xml"})  
public class Table1RepositoryTests {

    @Autowired
    private Table1Repository table1Repository;

    private Table1 table1;

    @Before
    public void setup(){
        table1 = new Table1();
        table1.setDescription("This is row 1 of table 1");
        table1.setId(1);
    }

    @Test
    public void shouldReturnFirstRowOfTable1(){
        Table1 result = table1Repository.retrieveTableById(1);
        assertEquals(result,table1);
    }

}

Update

It seems like I should inject SessionFactory object. As I have following line in my repository class.

    @Autowired
    private SessionFactory sessionFactory;

Also I've found following link that says "For example, do not write unit tests that make HTTP requests, access a database, or read from the filesystem." Then how am I supposed to test if my repository code is working?

  1. You can use HSQLDB to test the repository code. HSQLDB can be used as in memory mode, and re-construct each time you run the UnitTest.
  2. IMHO, it's recommended to only test the individual classes. So you'd better mock the sessionFactory and make it return whatever you want in Table1RepositoryTests.
  3. If you really want to test the injection logic of spring, and test Table1RepositoryImpl with sessionFactory, you can use the syntax @RunWith(SpringJUnit4ClassRunner.class) in your code. The exception is because of no such method orphanRemoval . Google it you can find answers in stackoverflow or blog

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM