Hi Hardy
Thanks for getting back to me. I tried the thing that the blogger mentioned but there was some unwanted side effects for example we have mapping definitions which as lazy="true" and attaching a jta manager to the session factory causes lazy initialisation exceptions. At home with the demo project i get an out of memory error when i attach a jta manager.
The only way we managed to get it working was by implementing an EmptyInterceptor and use Spring's TransactionSynchronizationAdapter to register tx and then do a flush to index. Here is the same code:
Code:
public class SearchTransactionInterceptor extends EmptyInterceptor implements BeanFactoryAware, InitializingBean {
private BeanFactory beanFactory;
private static final Logger log = Logger.getLogger(SearchTransactionInterceptor.class);
private final TransactionSynchronizationAdapter transactionSynchronizationAdapter;
public SearchTransactionInterceptor() {
transactionSynchronizationAdapter = new TransactionSynchronizationAdapter() {
@Override
public void beforeCommit(boolean readonly) {
flushToIndex();
}
@Override
public void afterCompletion(int status) {
if (status == STATUS_ROLLED_BACK)
log.error("Transaction rolled back after email messages were queued. EXPECT LOST EMAILS");
}
};
}
private void registerTransactionSynchronisation() {
// TransactionSynchronization is per thread so no need for synchronised block here
// otherwise would need to synchronise this method
List<?> synchronizations = TransactionSynchronizationManager.getSynchronizations();
if (!synchronizations.contains(transactionSynchronizationAdapter)) {
TransactionSynchronizationManager.registerSynchronization(transactionSynchronizationAdapter);
}
}
public void flushToIndex() {
registerTransactionSynchronisation();
log.debug("Flushing lucene work to indexes.");
SessionFactory sessionFactory = (SessionFactory) beanFactory.getBean("sessionFactory");
Session session = sessionFactory.getCurrentSession();
FullTextSession fullTextSession = Search.getFullTextSession(session);
fullTextSession.flushToIndexes();
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@Override
public void afterPropertiesSet() throws Exception {
}
@Override
public boolean onLoad(Object entity, Serializable id, Object[] state,
String[] propertyNames, Type[] types) {
if (TransactionSynchronizationManager.isSynchronizationActive()) {
registerTransactionSynchronisation();
}
return super.onLoad(entity, id, state, propertyNames, types);
}
}
This seems to work. To be honest I'm not really happy with the above solution.
I have a demo project which doesn't use the above but shows the problem that I am experiencing and I would be happy to send it to you or someone who may be able to help.
On a side note just wanted to say that we did show and tell of what we've done so far with Hibernate Search and our product and all the members were extremely pleased. So thanks guys!