SteveB
SteveB

Reputation: 533

Having a Spring dependency injection problem

I have an entity class thus

package org.mystuff.dao.entity;

@Entity
public class Result {
   @Id
   private int id;
   private int someStuff;

   public Result(int someStuff) {
       this.someStuff = someStuff;
   }

   public int getSomeStuff() {
       return someStuff;
   }

   public void setSomeStuff(int SomeStuff) {
       this.someStuff = someStuff;
   }
}

I have a repository

package org.mystuff.dao.repo;

@Repository
@Transactional
public interface ResultRepository extends JpaRepository<Result, Long> {

    List<Result> getResultByDate(Date date);

}

I have a couple of component classes

package org.mystuff.dostuff;

@Component
public class UsefulClassA {

    @Autowired
    private ResultRepository resultRepository;

    @Autowired
    private SomethingUseful somethingUseful;

    private Date date;

    public void doStuff() {
        List<Result> resultList = resultRepository.getResultByDate(date);
        // Do something with resultList
    }
}

and

package org.mystuff.dostuff;

@Component
public class UsefulClassB {

    @Autowired
    private SomethingElseUseful somethingElseUseful;

    private int a;

    public void myMethod(int b)  {
       a = b;
    }

 }

I have an test config class

package org.mystuff.test.config;

@RunWith(SpringRunner.class)
@ComponentScan(basePackages = "org.mystuff.dostuff")
@EnableJpaRepositories(basePackages = "org.mystuff.dao.repo", entityManagerFactoryRef = "mystuffEntityManagerFactory")
public class AppTestConfig {

    @Bean
    LocalContainerEntityManagerFactoryBean mystuffEntityManagerFactory() {
    
       final LocalContainerEntityManagerFactoryBean myEntityManagerFactoryBean = 
                  new.LocalContainerEntityManagerFactoryBean();
       myEntityManagerFactoryBean.setDataSource(myDataSource);
       myEntityManagerFactoryBean.setPackagesToScan("org.mystuff.dao.entity")
       return myEntityManagerFactoryBean;    
    }
}

And finally, my test class

package org.mystuff.test;

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = AppTestConfig.class)
public MyBigTestClass {

    @Autowired
    private UsefulClassB usefulClassB;

    @Before
    public void beforeStuff() {
        // Do some before stuff
    }

    @Test
    public void doATest() {
        usefulClassB.doSomethingUseful();
    }

}

I get an exception caused by this

Error creating bean with name 'resultRepository': Invocation of init method failed: nested exception is java.lang.IllegalArgumentException: Not a managed type: org.mystuff.dao.entity.Result

First, why is the container trying to instantiate resultRepository? It's not in the class I'm testing. Second, why is it saying that Result is not a managed type when it clearly is?

Upvotes: 0

Views: 53

Answers (3)

SteveB
SteveB

Reputation: 533

I'm not sure why, but the problem was solved by making UsefulClassA a prototype bean. I assume that since it was a singleton, it could possibly be used in a way that the dependency container didn't know about, so it instantiated it.

Thank you for the answers. They led me to the solution.

Upvotes: 0

Tushar Jajodia
Tushar Jajodia

Reputation: 451

You have two ways to solve the issues. Choose which suits your conditions.

  1. Changing org.mystuff.dao to org.mystuff.dostuff.dao for both ResultRepository and Result.
  2. The other one is chaning the @ComponentScan(basePackages = "org.mystuff.dostuff") in AppTestConfig to @ComponentScan(basePackages = "org.mystuff")

@ComponentScan will cause spring to manage only those beans (annotated by @Component, @Service and other @Bean Annotation) which are under the basePackage. You are giving basePackage as org.mystuff.dostuff so the @Bean Result and ResulRepo are not managed by Spring as they are out of the basePackage supplied.

Upvotes: 0

khoibv
khoibv

Reputation: 369

I think that you are not scanning package containing Entity

// your entity package is 
package org.mystuff.dao.entity;

// but you are scanning at `org.mystuff.dostuff`
@ComponentScan(basePackages = "org.mystuff.dostuff")

Please, let try to change it to

@ComponentScan(basePackages = "org.mystuff")

Upvotes: 1

Related Questions