Configure beans file for repositories

Viewed 3542

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

2 Answers

You must desclare alias for these beans

For example

<bean id="mysqlService" lazy-init="true" alias="mysqlrepoAlias"
 class="ee3.demo.repositories.mysql.UserRepository"/>

<bean id="mongorepoService" lazy-init="true"  alias="mongorepoAlias"class="ee3.demo.repositories.mysql.UserRepository"/>

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>
Related