Search code examples
springspring-mvcjavabeans

Configure beans file for repositories


I have two interface with same name but in different packages. As I autowired them I have to give them name. My interfaces are com.example.mysql.UserRepository and com.example.mongo.UserRepository.

So I have declared them like this:

@Repository(value = "mysqlrepo")
public interface UserRepository extends JpaRepository<User,Long> ...

and

@Repository(value = "mongorepo")
public interface UserRepository extends MongoRepository<User,String> ...

and used them like this:

@Autowired
ee3.demo.repositories.mysql.UserRepository userRepository;

@Qualifier("mongorepo")
@Autowired
UserRepository userRepository1;

Now I wonder how can I do this with beans configure file. I tried <bean id="mysqlService" lazy-init="true" class="ee3.demo.repositories.mysql.UserRepository"/> but I am getting error interface not allowed for non abstract beans. I wondering what is the correct way of doing this, this question if different with this question as this question have just one interface and don't need to use qualifier to specify which interface he need What I have tried so far is HERE


Solution

  • If you want to configure Spring Data using XML config you don't need to declare beans for all your repositories. See Spring Data docs here. It's easier to specify a base package for scanning:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:jpa="http://www.springframework.org/schema/data/jpa"
      xmlns:mongo="http://www.springframework.org/schema/data/mongo"
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/data/jpa 
        http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd
        http://www.springframework.org/schema/data/mongo
        http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd">
    
      <!-- 
        Configure Spring Data JPA / MongoDB and set the base package of the 
        repository interfaces 
      -->
      <jpa:repositories base-package="com.example.mysql"/>
      <mongo:repositories base-package="com.example.mongo"/>
    
     ...
    

    Read more in this post.


    EDIT

    You need to give different names to your repositories (use value attribute on annotation). I suspect that if you have multiple interfaces with the same name UserRepository, all of them would be overridden by the latest declared bean. This is a modified code from GitHub

    DemoApplication.java

    @SpringBootApplication
    //@ImportResource("classpath:beans.xml")
    public class DemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }
    

    beans.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    </beans>
    

    mysql.UserRepository.java

    @Repository(value = "userRepositoryJpa")
    public interface UserRepository extends JpaRepository<User,Long> {
        User findByName(String name);
    }
    

    mongodb.UserRepository.java

    @Repository(value = "userRepositoryMongo")
    public interface UserRepository extends MongoRepository<UserMongo, String> {
        User findByName(String name);
    }
    

    EDIT 2

    Another option is to write your own implementations for these interfaces and reference them from XML. You need to remove @Repository, @EnableJpaRepositories, @EnableMongoRepositories annotations also. You need to implement all methods by yourself. But you lose the benefits of Spring Data... Look for Custom implementations for Spring Data repositories in docs.

    public interface UserRepositoryImpl implements UserRepository {
        public User findByName(String name) {
            // your custom implementation
        }
    }
    

    XML Configuration example

    <jpa:repositories base-package="com.example.repositories.mysql" repository-impl-postfix="Impl" />  
    <mongo:repositories base-package="com.example.repositories.mongodb" repository-impl-postfix="Impl" />  
    
    <beans:bean id="jpaUserRepositoryImpl" class="com.example.repositories.mysql.UserRepositoryImpl">
    </beans:bean>
    
    <beans:bean id="mongoUserRepositoryImpl" class="com.example.repositories.mongodb.UserRepositoryImpl">
    </beans:bean>