spring-projects / spring-data-neo4j

Provide support to increase developer productivity in Java when using Neo4j. Uses familiar Spring concepts such as a template classes for core API usage and lightweight repository style data access.
http://spring.io/projects/spring-data-neo4j
Apache License 2.0
831 stars 618 forks source link

Null pointer after rollback in test [DATAGRAPH-952] #1514

Closed spring-projects-issues closed 7 years ago

spring-projects-issues commented 7 years ago

Mark Angrish opened DATAGRAPH-952 and commented

I have a test which tests an exception is thrown for a data integrity violation.

The structure is essentially:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(....)
@Transactional
@Rollback // optional here, 
public class MyTest {
...
    @Test(expected = DataIntegrityViolationException.class)
    public void shouldTrowRollbackException() throws Exception {
    ...
    }
}

Whole test case is linked in the Reference URL:

Using versions: SDN 4.2.0-BUILD-SNAPSHOT OGM: 2.1.0

Exception:

java.lang.NullPointerException
    at org.springframework.data.neo4j.transaction.Neo4jTransactionManager.doRollback(Neo4jTransactionManager.java:275)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:853)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:830)
    at org.springframework.test.context.transaction.TransactionContext.endTransaction(TransactionContext.java:125)
    at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:227)
    at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:319)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:94)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Affects: 4.2 RC1 (Ingalls), 5.0 M1 (Kay)

Reference URL: https://gist.github.com/frant-hartm/eb54c6ca346f4c5cee2636a1bbead404

Backported to: 4.2.8 (Ingalls SR8)

3 votes, 5 watchers

spring-projects-issues commented 7 years ago

Mark Angrish commented

Same problem. As explained here, this class has been patched for the user's application to correctly work: http://stackoverflow.com/questions/39696304/rollback-problems-with-new-neo4jtransactionmanager

spring-projects-issues commented 7 years ago

kostas commented

Hi, I think this one should be upgraded to major since there are many cases that this can affect the workflow. E.g imagine the following scenario. I have a node with a unique constraint on property ``` id

I have a method that tries to create a node, it catches the unique constraint violation in case it is thrown from the underlying boltrequest, when it does it wants to continue the flow. But instead a NullPointerException is thrown because of this issue. So it breaks the functionality. *Currently the only workaround i could think of* is to avoid using the @Transactional in order to NOT at all use the Neo4jTransactionManager

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = java.lang.Exception.class) public void createNode(Long id){ Node sampleNode=new Node(id); sampleNode.setMyName("kostas"); try{ myNodeNeo4jRepository.save(sampleNode); }catch(ClientException ex){
if (exception.getMessage() != null && exception.code().equals("Neo.ClientError.Schema.ConstraintValidationFailed")) { String msg = "A node with the same id already exists in neo4j ,uniqueId is:" + sampleNode.getId(); LOGGER.warn(msg, exception);

} else {
    throw exception;
}

} }

public void mulithreadedLogicThatCreatesNodes(){ List\ idsTocreate=getIdsToCreate(); for(Long id:myNodeIds){ createNode(id); } }

spring-projects-issues commented 7 years ago

Nicolas Mervaillie commented

Fixed in DATAGRAPH-997