2

I want to have access to multiple/2 repos in one service using spring-data-solr. From Spring Data Solr multiple cores and repository I know 'multicore support via namespace config is unfortunately an open issue'.

Can you please help me with the following example, how can I create custom Repos?

My applicationContext.xml has two Solr Templates defined as below:

<!-- Enable Solr repositories and configure repository base package -->
<solr:repositories base-package="com.ay.api.repository"/>

<!-- Configures HTTP Solr server -->
<solr:solr-server id="solrServer" url="${solr.server.url}"/>

<!-- Configures Solr Events template -->
   <bean id="solrEventsTemplate" class="org.springframework.data.solr.core.SolrTemplate">
   <qualifier type="solrEventsTemplate"/>
   <constructor-arg index="0" ref="solrServer"/>
   <constructor-arg index="1" value="${solr.server.events.core.name}"/>
</bean>

<!-- Configures Solr Towns template -->
<bean id="solrTownsTemplate" class="org.springframework.data.solr.core.SolrTemplate">
<constructor-arg index="0" ref="solrServer"/>
<constructor-arg index="1" value="${solr.server.towns.core.name}"/>
</bean>

and I have following repos

@Repository
public class EventDocumentRepositoryImpl implements EventSearchRepository { 


@Resource
@Qualifier("solrEventsTemplate")
private SolrTemplate solrEventsTemplate;

...
}

public interface EventDocumentRepository extends EventSearchRepository, SolrCrudRepository<EventDocument, String> {

}

public interface EventSearchRepository { .... }


@Repository
public class TownRepositoryImpl implements TownSearchRepository { ... 

@Resource
@Qualifier("solrTownsTemplate")
private SolrTemplate solrTownsTemplate;

...
}

public interface TownRepository extends SolrCrudRepository<TownDocument, String>{}
public interface TownSearchRepository { .... }

and lastly Service looks like following:

 @Service
 public class SearchEventServiceImpl implements SearchEventService {

 @Resource
 private EventDocumentRepository eventRepository;

 @Resource
 private TownRepository townRepository;
 .....
 }

Can someone please advice how can I modify my code to Implement Custom repositories as mentioned in Spring Data Solr with Solr 4.1 multicores ? as I couldn't understand suggested solution in this thread.

Many thanks in Advance.

Community
  • 1
  • 1
Aamir Yaseen
  • 487
  • 6
  • 20
  • Multiple cores with multiple repository can now be setup as explained here http://stackoverflow.com/questions/35378648/how-to-configure-spring-data-solr-with-repositories-for-multiple-cores/35379501#35379501 – Nikhil Sahu Feb 13 '16 at 12:18

2 Answers2

5

Repository scanning will look for solrTemplate and create repository using provided template. As you need one template for each Solr core, you'll have to create both, template and repository manually.

First create your repositories and custom implementations.

public interface EventRepositoryCustom {

    Page<Event> findEvent();

}

public interface EventRepository extends EventRepositoryCustom, SolrCrudRepository<Event, String> {

}

public class EventRepositoryImpl implements EventRepositoryCustom {

    private SolrTemplate eventTemplate;

    public EventRepositoryImpl(SolrTemplate eventTemplate) {
        this.eventTemplate = eventTemplate;
    }

    @Override
    public Page<Event> findEvent() {
        return eventTemplate.queryForPage(new SimpleQuery("*:*"), Event.class);
    }

}

Do the same for your TownRepository.

Using Java Config for configuration. Same can be done with XML.

@Configuration
public class SolrContext {

  private static final String PROPERTY_NAME_SOLR_SERVER_URL = "solr.host";

  @Resource
  private Environment environment;

  // Factory creates SolrServer instances for base url when requesting server
  // for specific core. 
  @Bean
  public SolrServerFactory solrServerFactory() {
    return new MulticoreSolrServerFactory(new HttpSolrServer(
            environment.getRequiredProperty(PROPERTY_NAME_SOLR_SERVER_URL)));
  }

  // SolrTemplate for /solrServerUrl/towns
  @Bean
  public SolrTemplate townTemplate() throws Exception {
    SolrTemplate solrTemplate = new SolrTemplate(solrServerFactory());
    solrTemplate.setSolrCore("towns");
    return solrTemplate;
  }

  // SolrTemplate for /solrServerUrl/events
  @Bean
  public SolrTemplate eventTemplate() throws Exception {
    SolrTemplate solrTemplate = new SolrTemplate(solrServerFactory());
    solrTemplate.setSolrCore("events");
    return solrTemplate;
  }

  @Bean
  public EventRepository eventRepository() throws Exception {
    return new SolrRepositoryFactory(eventTemplate())
      .getRepository(EventRepository.class, new EventRepositoryImpl(eventTemplate()));
  }

  @Bean
  public TownRepository townRepository() throws Exception {
    return new SolrRepositoryFactory(townTemplate())
      .getRepository(TownRepository.class, new TownRepositoryImpl(townTemplate()));
  }
}
Christoph Strobl
  • 6,491
  • 25
  • 33
  • Like always, Spot on and perfect solution. Many Thanks for the quick Reply. Cheers – Aamir Yaseen Jan 02 '14 at 17:13
  • @Christoph-Strobl, the posted answer apparently, according to Spring, no longer works: https://github.com/spring-projects/spring-boot/issues/2687. How did your solution work without this auto-configuration capability? We really need to find a way to use multiple solr instances and have run into nothing but problems. – caro Jul 07 '15 at 18:35
  • This does not work on the latest spring-data-solr. Classes have been removed (e.g. SolrServerFactory ). Any solution? – checklist Nov 17 '16 at 07:02
  • just use the according `SolrClientFactory`. – Christoph Strobl Nov 17 '16 at 07:42
  • Hi, using the latest spring data, this does not work. The repository gets the core from the entity. this causes an error since it tries to do a select on `Error from server at http://localhost:8983/solr/events/events/select [...] Error 404 Not Found` the template works correctly. – sokie Jan 23 '17 at 13:25
  • @ChristophStrobl, is it possible to do something like this using Spring Data Solr's @Query(...)-Annotations? I would like to avoid re-implementing the query logic Spring is generating automatically for me. – Paul Wellner Bou Dec 04 '17 at 12:11
0

when i did this as suggest in the answer, i got PersistenceExceptionTranslator exception, so i initialize this bean manually:

<beans:bean id="PersistenceExceptionTranslator" class="org.springframework.data.solr.core.SolrExceptionTranslator"/>
Itai Peleg
  • 39
  • 3