/*
* Copyright (c) [2011-2016] "Pivotal Software, Inc." / "Neo Technology" / "Graph Aware Ltd."
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product may include a number of subcomponents with
* separate copyright notices and license terms. Your use of the source
* code for these subcomponents is subject to the terms and
* conditions of the subcomponent's license, as noted in the LICENSE file.
*
*/
package org.springframework.data.neo4j.transactions;
import static org.junit.Assert.*;
import java.util.Iterator;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.neo4j.ogm.session.SessionFactory;
import org.neo4j.ogm.testutil.MultiDriverTestClass;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.transaction.Neo4jTransactionManager;
import org.springframework.data.neo4j.transactions.service.ServiceA;
import org.springframework.data.neo4j.transactions.service.ServiceB;
import org.springframework.data.neo4j.transactions.service.WrapperService;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;
/**
* @author: Vince Bickers
* @see http://stackoverflow.com/questions/17224887/java-spring-transactional-method-not-rolling-back-as-expected
* @see DATAGRAPH-602
*/
@ContextConfiguration(classes = {ExtendedTransactionsTests.ApplicationConfig.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class ExtendedTransactionsTests extends MultiDriverTestClass {
@Autowired
ServiceA serviceA;
@Autowired
ServiceB serviceB;
@Autowired
WrapperService wrapperService;
@Before
public void clearDatabase() {
getGraphDatabaseService().execute("MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE r, n");
}
@Test
public void shouldRollbackSuccessThenFail() {
try {
wrapperService.composeSuccessThenFail();
fail("should have thrown exception");
} catch (Exception e) {
assertEquals("Deliberately throwing exception", e.getLocalizedMessage());
assertEquals(0, countNodes());
}
}
@Test
@Transactional
@Rollback
public void shouldCommitSuccessSuccess() {
try {
wrapperService.composeSuccessThenSuccess();
assertEquals(2, countNodes());
} catch (Exception e) {
fail("should not have thrown exception");
}
}
@Test
public void shouldRollbackFailThenSuccess() {
try {
wrapperService.composeFailThenSuccess();
fail("should have thrown exception");
} catch (Exception e) {
assertEquals("Deliberately throwing exception", e.getLocalizedMessage());
assertEquals(0, countNodes());
}
}
@Test
public void shouldRollbackFailThenFail() {
try {
wrapperService.composeFailThenFail();
fail("should have thrown exception");
} catch (Exception e) {
assertEquals("Deliberately throwing exception", e.getLocalizedMessage());
assertEquals(0, countNodes());
}
}
@Test
public void shouldRollbackWithCheckedException() {
try {
wrapperService.rollbackWithCheckedException();
fail("should have thrown exception");
} catch (Exception e) {
assertEquals("Deliberately throwing exception", e.getLocalizedMessage());
assertEquals(0, countNodes());
}
}
@Test
public void shouldRollbackRepositoryMethodOnCheckedException() {
try {
serviceA.run();
} catch (Exception e) {
assertNull(serviceB.getBilbo());
}
}
private int countNodes() {
Iterator iterator = wrapperService.fetch().iterator();
int i = 0;
while (iterator.hasNext()) {
iterator.next();
i++;
}
return i;
}
@Configuration
@ComponentScan("org.springframework.data.neo4j.transactions.service")
@EnableTransactionManagement
@EnableNeo4jRepositories("org.springframework.data.neo4j.transactions.repo")
static class ApplicationConfig {
@Bean
public PlatformTransactionManager transactionManager() {
return new Neo4jTransactionManager(sessionFactory());
}
@Bean
public SessionFactory sessionFactory() {
return new SessionFactory(getBaseConfiguration().build(),"org.springframework.data.neo4j.transactions.domain");
}
}
}