I'm trying to integrate Hibernate Search in my application. Rough summary of what needs to be done:
- Spring Batch reads out an XML file and persists the objects to database. This is done with de JDBCBatchItemWriter. Not the HibernateItemWriter because of slow performance.
- After all items are inserted I would like to build the Hibernate Search/Lucene index.
The problem is in the last step. Nothing is being indexed.
The setup is as follows:
There is a JobListener where I index the data in my database like so:
Session session = sessionFactory
.withOptions()
.openSession();
FullTextSession fullTextSession = Search.getFullTextSession(session);
try {
fullTextSession.createIndexer().startAndWait();
} catch (InterruptedException e) {
e.printStackTrace();
}
But when I check my index with Luke I can't find any records in it. I guess it is has something to do with transactions but I can't figure out how to make it work.
This my persistence configuration:
@Bean
public EntityManagerFactory entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setPackagesToScan("xxx.data.domain");
entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.getJpaPropertyMap().putAll(jpaProperties());
entityManagerFactoryBean.afterPropertiesSet();
return entityManagerFactoryBean.getObject();
}
@Bean
public FullTextEntityManager fullTextEntityManager(EntityManager entityManagerFactory) throws InterruptedException {
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManagerFactory);
fullTextEntityManager.createIndexer().startAndWait();
return fullTextEntityManager;
}
private Map<String, String> jpaProperties() {
Map<String, String> jpaProperties = new HashMap<String, String>();
jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.OracleDialect");
jpaProperties.put("hibernate.search.default.directory_provider", "filesystem");
jpaProperties.put("hibernate.search.default.indexBase", "/tmp/lucene/indexes");
jpaProperties.put("hibernate.search.indexing_strategy", "manual");
return jpaProperties;
}
@Bean
public SessionFactory sessionFactory(DataSource dataSource) throws IOException {
LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
localSessionFactoryBean.setDataSource(dataSource);
localSessionFactoryBean.setPackagesToScan("xxx.data.domain");
localSessionFactoryBean.afterPropertiesSet();
return localSessionFactoryBean.getObject();
}
Entity to be indexed:
@Entity
@Table(name = "MY_TABLE")
@Indexed
public class EntryEntity {
public static final String SEQUENCE_NAME = "SEQ_MY_TABLE";
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SEQUENCE_NAME)
@SequenceGenerator(name = SEQUENCE_NAME, sequenceName = SEQUENCE_NAME, allocationSize = 1)
@Column(name = "ID")
private Long id;
@Column(name = "ENTRY_ID")
@Field(index = Index.YES, analyze = Analyze.NO, store = Store.YES)
private String entryIdentifier;
@Column
@Field(index = Index.YES, analyze = Analyze.NO, store = Store.YES)
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
I think the problem is that you defining your Search properties in jpaProperties which is processed by the entity manager. When you call the mass indexer, however, you are using a plain Session. In this case the JPA properties will not be picked up. My guess is that there is some index directory created relative to where you start your JVM. Really you should always work with the
EntityManager
. There is also aorg.hibernate.search.jpa.Search
which allows you to get hold of aFullTextEntityManager
.