package com.mysema.luja.impl;
import static com.mysema.luja.QueryTestHelper.createDocument;
import static com.mysema.luja.QueryTestHelper.createDocuments;
import static com.mysema.luja.QueryTestHelper.getDocument;
import static org.junit.Assert.*;
import org.apache.lucene.store.RAMDirectory;
import org.junit.Before;
import org.junit.Test;
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
import com.mysema.luja.LuceneSession;
import com.mysema.luja.LuceneSessionFactory;
import com.mysema.luja.LuceneTransactional;
import com.mysema.luja.SessionNotBoundException;
import com.mysema.luja.SessionReadOnlyException;
import com.mysema.luja.mapping.domain.QMovie;
import com.mysema.query.lucene.LuceneQuery;
public class LuceneTransactionalHandlerTest {
private LuceneSessionFactory sessionFactory;
private final LuceneTransactionHandler handler = new LuceneTransactionHandler();
private TestDao testDao;
private QMovie path = new QMovie("doc");
@Before
public void before() {
sessionFactory = new LuceneSessionFactoryImpl(new RAMDirectory());
AspectJProxyFactory factory = new AspectJProxyFactory(new TestDaoImpl(sessionFactory));
factory.addAspect(handler);
testDao = factory.getProxy();
}
private NestedDao getNestedDao(LuceneSessionFactory sf) {
AspectJProxyFactory factory = new AspectJProxyFactory(
new NestedDaoImpl(sf));
factory.addAspect(handler);
return factory.getProxy();
}
@Test
public void Empty() {
testDao.empty();
assertEquals(1, testDao.count());
}
@Test(expected = SessionNotBoundException.class)
public void NoAnnotation() {
testDao.noAnnotation();
}
@Test
public void Annotation() {
testDao.annotation();
assertEquals(1, testDao.count());
}
@Test(expected = SessionReadOnlyException.class)
public void ReadOnly() {
testDao.readOnly();
}
@Test
public void Writing() {
testDao.writing();
LuceneQuery q = sessionFactory.openReadOnlySession().createQuery();
assertEquals(4, q.where(path.title.like("*")).count());
}
@Test
public void Multifactories() {
LuceneSessionFactory sf1 = new LuceneSessionFactoryImpl(new RAMDirectory());
LuceneSessionFactory sf2 = new LuceneSessionFactoryImpl(new RAMDirectory());
LuceneSessionFactory sf3 = new LuceneSessionFactoryImpl(new RAMDirectory());
AspectJProxyFactory factory = new AspectJProxyFactory(new TestDaoImpl(sf1,sf2,sf3));
factory.addAspect(handler);
testDao = factory.getProxy();
testDao.multiFactories();
LuceneQuery q = sf1.openReadOnlySession().createQuery();
assertEquals(1, q.where(path.title.eq("sf1")).count());
q = sf2.openReadOnlySession().createQuery();
assertEquals(1, q.where(path.title.eq("sf2")).count());
q = sf3.openReadOnlySession().createQuery();
assertEquals(1, q.where(path.title.eq("sf3")).count());
}
@Test
public void NestedSession() {
AspectJProxyFactory factory = new AspectJProxyFactory(new NestedDaoImpl(sessionFactory));
factory.addAspect(handler);
NestedDao nestedDao = factory.getProxy();
testDao.setNested(nestedDao);
testDao.nested();
LuceneSession session = sessionFactory.openReadOnlySession();
assertEquals(1, session.createQuery().where(path.title.eq("nested")).count());
session.close();
}
@Test
public void RuntimeExceptionCausesRollback() {
boolean gotExp = false;
try {
testDao.throwsException();
} catch (RuntimeException e) {
gotExp = true;
}
LuceneQuery q = sessionFactory.openReadOnlySession().createQuery();
assertEquals(0, q.where(path.title.eq("rollback")).count());
assertEquals("Should have gotten exception", true, gotExp);
}
@Test
public void CheckedExceptionCauseRollback() {
boolean gotExp = false;
try {
testDao.throwsCheckedException();
} catch (Exception e) {
gotExp = true;
}
LuceneQuery q = sessionFactory.openReadOnlySession().createQuery();
assertEquals(0, q.where(path.title.eq("rollback-checked")).count());
assertEquals("Should have gotten exception", true, gotExp);
}
@Test
public void NestedExceptionRollback() {
testDao.setNested(getNestedDao(sessionFactory));
boolean gotExp = false;
try {
testDao.nestedException();
} catch (Exception e) {
gotExp = true;
}
LuceneQuery q = sessionFactory.openReadOnlySession().createQuery();
assertEquals(0, q.where(path.title.eq("nested rollback")).count());
assertEquals(0, q.where(path.title.eq("nested")).count());
assertEquals("Should have gotten exception", true, gotExp);
}
@Test
public void NestedExceptionWithDifferentSession() {
LuceneSessionFactory sf1 = new LuceneSessionFactoryImpl(new RAMDirectory());
testDao.setNested(getNestedDao(sf1));
boolean gotExp = false;
try {
testDao.nestedException();
} catch (Exception e) {
gotExp = true;
}
LuceneQuery q = sf1.openReadOnlySession().createQuery();
assertEquals(0, q.where(path.title.eq("nested rollback")).count());
q = sessionFactory.openReadOnlySession().createQuery();
assertEquals(0, q.where(path.title.eq("nested")).count());
assertEquals("Should have gotten exception", true, gotExp);
}
private static interface TestDao {
void empty();
int count();
void noAnnotation();
void annotation();
void readOnly();
void writing();
void multiFactories();
void nested();
void setNested(NestedDao nested);
void throwsException();
void throwsCheckedException() throws Exception;
void nestedException();
}
private static class TestDaoImpl implements TestDao {
private int count = 0;
private final LuceneSessionFactory[] factories;
private NestedDao nested;
TestDaoImpl(LuceneSessionFactory ... factories) {
this.factories = factories;
}
@Override
@LuceneTransactional
public void empty() {
count++;
}
@Override
public int count() {
return count;
}
@Override
public void noAnnotation() {
factories[0].getCurrentSession();
}
@Override
@LuceneTransactional
public void annotation() {
count++;
factories[0].getCurrentSession();
}
@Override
@LuceneTransactional(readOnly=true)
public void readOnly() {
LuceneSession session = factories[0].getCurrentSession();
session.beginAppend().addDocument(getDocument());
}
@Override
@LuceneTransactional
public void writing() {
LuceneSession session = factories[0].getCurrentSession();
createDocuments(session);
}
@Override
@LuceneTransactional
public void multiFactories() {
LuceneSession s1 = factories[0].getCurrentSession();
LuceneSession s2 = factories[1].getCurrentSession();
LuceneSession s3 = factories[2].getCurrentSession();
s1.beginReset().addDocument(createDocument("1", "sf1","","",0,0));
s2.beginReset().addDocument(createDocument("2", "sf2","","",0,0));
s3.beginReset().addDocument(createDocument("3", "sf3","","",0,0));
}
@Override
public void setNested(NestedDao nested) {
this.nested = nested;
}
@Override
@LuceneTransactional
public void nested() {
LuceneSession session = factories[0].getCurrentSession();
session.beginReset().addDocument(createDocument("1", "nested","","",0,0));
nested.nested();
}
@Override
@LuceneTransactional
public void nestedException() {
LuceneSession session = factories[0].getCurrentSession();
session.beginAppend().addDocument(createDocument("1", "nested","","",0,0));
nested.nestedException();
}
@Override
@LuceneTransactional
public void throwsException() {
LuceneSession session = factories[0].getCurrentSession();
session.beginAppend().addDocument(createDocument("1", "rollback","","",0,0));
throw new RuntimeException();
}
@Override
@LuceneTransactional
public void throwsCheckedException() throws Exception {
LuceneSession session = factories[0].getCurrentSession();
session.beginAppend().addDocument(createDocument("1", "rollback-checked","","",0,0));
throw new Exception();
}
}
private static interface NestedDao {
void nested();
void nestedException();
}
private class NestedDaoImpl implements NestedDao {
private final LuceneSessionFactory sessionFactory;
public NestedDaoImpl(LuceneSessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
@LuceneTransactional
public void nested() {
LuceneSession session = sessionFactory.getCurrentSession();
LuceneQuery query = session.createQuery();
assertEquals(0, query.where(path.title.eq("nested")).count());
// This verifies that the we are using the same session opened in
// the caller scope
session.commit();
query = session.createQuery();
assertEquals(1, query.where(path.title.eq("nested")).count());
}
@Override
@LuceneTransactional
public void nestedException() {
LuceneSession session = sessionFactory.getCurrentSession();
session.beginAppend().addDocument(createDocument("1", "nested rollback","","",0,0));
throw new RuntimeException();
}
}
}