Pergunta

I have a big issue with the dependency jnjection of Spring. I created a class ObjectJPA, that implements my DAO interface. Now I want to test it within a JUnit testcase. But I get a NoSuchBeanDefinitionException.

This is the beginning of the test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:Spring-Common.xml" })
public class Test {

  @Autowired
  ObjectJPA jpa;

}

And this is the bean

package model.dao.jpa;

@Repository
public class ObjectJPA implements ObjectDAO { … }

content of the Spring-Common.xml

<bean class="….ObjectJPA" />

the declaration of the interface

package model.dao;

public interface ObjectDAO {

Content of the Spring-Common.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:p="http://www.springframework.org/schema/p"
       xmlns:tx="http://www.springframework.org/schema/tx"
   xmlns:context="http://www.springframework.org/schema/context"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

   <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

   <context:component-scan base-package="model.dao.jpa" />

   <bean class="model.dao.jpa.ObjectJPA" />
   <bean id="entityManagerFactory"  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
     <property name="persistenceUnitName" value="model" />
     <property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml" />
     <property name="jpaVendorAdapter">
       <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
     </property>
   </bean>

   <context:annotation-config />
   <tx:annotation-driven />

 </beans>

Do you have any ideas? Which information do you need to get a better impact?

Foi útil?

Solução

The actual type of the bean, for Spring, is the type of its interface, and not its concrete type. So you should have

@Autowired
private ObjectDAO jpa;

and not

@Autowired
private ObjectJPA jpa;

Indeed, Spring by default uses Java interface proxies to implement AOP. And it thus needs to inject its own proxy, which implements all the interfaces of your bean and wraps it, but is not an instance of its concrete class. And that's not a problem, because the whole point of using interfaces is to use them when referencing objects, rather than using the concrete type of the object (just like you use the type List to refer to a List, and not the type ArrayList).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top