How to Implement custom Solr Repository using Spri

2019-02-11 09:41发布

问题:

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.

回答1:

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()));
  }
}


回答2:

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"/>