Spring Data Solr and Mongo CDI

612 views Asked by At

I am trying to use both spring data solr and spring data mongo in a Java EE project. Problem is both

https://github.com/spring-projects/spring-data-mongodb/blob/master/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/cdi/MongoRepositoryExtension.java

and

https://github.com/spring-projects/spring-data-solr/blob/master/src/main/java/org/springframework/data/solr/repository/cdi/SolrRepositoryExtension.java

try to inject MongoOperations and SolrOperations to the Repository. Afterwards both create repositories and then I end up with an ambiguous cdi dependency exception. Looking at the source code here

https://github.com/spring-projects/spring-data-commons/blob/master/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryExtensionSupport.java

there does not seem to be a way to distinguish between solr repositories and mongo repositories. Is there any solution?

1

There are 1 answers

1
ALienZ On BEST ANSWER

I am facing the same problems with spring data neo4j and spring data mongo.

The current implementation of afterBeanDiscovery() in CdiRepositoryExtensionSupport.java create bean instance for all repositories. When you use more than one Spring-Data-xxx there are multiple bean references in the context and ambigous name exception occur.

In order to make it work i do:

  1. checkout the spring sources of spring-data-mongo
  2. add an annotation in cdi package : @MongoRepositoryCdi
  3. Annotated the mongoRepository interface with @MongoRepositoryCdi
  4. in afterBeanDiscovery method verify if @MongoRepositoryCdi is present before create the repository bean
  5. Do the same things in Neo4j lib

After...it works!

Maybe it is not the best way to solve this issue and the guys at Spring Data project can find a better solution

CdiRepositoryExtensionSupport.java

void afterBeanDiscovery(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) {

    for (Entry<Class<?>, Set<Annotation>> entry : getRepositoryTypes()) {

        Class<?> repositoryType = entry.getKey();
        Set<Annotation> qualifiers = entry.getValue();

        if (repositoryType.isAnnotationPresent(MongoRepositoryCdi.class)) {
            // Create the bean representing the repository.
            CdiRepositoryBean<?> repositoryBean = createRepositoryBean(repositoryType, qualifiers, beanManager);

            if (LOG.isInfoEnabled()) {
                LOG.info(String.format("Registering bean for %s with qualifiers %s.", repositoryType.getName(), qualifiers));
            }

            // Register the bean to the container.
            registerBean(repositoryBean);
            afterBeanDiscovery.addBean(repositoryBean);
        }
    }
}

Repository

@Eager @MongoRepositoryCdi public interface TestDocumentRepository extends MongoRepository<TestDocument, String>{}

Hope this help!