diff --git a/pom.xml b/pom.xml index 7e0279a0b..fec034718 100644 --- a/pom.xml +++ b/pom.xml @@ -114,6 +114,11 @@ spring-aspects ${spring.version} + + org.springframework + spring-jdbc + ${spring.version} + org.springframework spring-tx @@ -130,6 +135,13 @@ data-commons 1.0.0.CI-SNAPSHOT + + + + org.hsqldb + hsqldb + 1.8.0.10 + diff --git a/src/main/java/org/springframework/persistence/transaction/NaiveDoubleTransactionManager.java b/src/main/java/org/springframework/persistence/transaction/NaiveDoubleTransactionManager.java new file mode 100644 index 000000000..653c9e44e --- /dev/null +++ b/src/main/java/org/springframework/persistence/transaction/NaiveDoubleTransactionManager.java @@ -0,0 +1,69 @@ +package org.springframework.persistence.transaction; + +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.TransactionException; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.DefaultTransactionStatus; + +public class NaiveDoubleTransactionManager implements PlatformTransactionManager { + + private final PlatformTransactionManager a; + + private final PlatformTransactionManager b; + + public NaiveDoubleTransactionManager(PlatformTransactionManager a, PlatformTransactionManager b) { + System.err.println("WARNING: Naive JTA/Neo4j Spring transaction manager--must implement properly"); + this.a = a; + this.b = b; + } + + @Override + public void commit(TransactionStatus ts) throws TransactionException { + TransactionStatus tsb = copyTransactionStatus(ts); + try { + a.commit(ts); + } + catch (Throwable t) { + System.err.println("Continuing to commit tx despite this:" + t); + } + try { + b.commit(tsb); + } + catch (Throwable t) { + System.err.println("Can't commit tx" + t); + throw new TransactionException(t.getMessage(), t) {}; + } + } + + private TransactionStatus copyTransactionStatus(TransactionStatus ts) { + return new DefaultTransactionStatus(null, ts.isNewTransaction(), false, false, false, null); + } + + @Override + public TransactionStatus getTransaction(TransactionDefinition td) + throws TransactionException { + TransactionStatus atx = a.getTransaction(td); + TransactionStatus btx = b.getTransaction(td); + return atx; + } + + @Override + public void rollback(TransactionStatus ts) throws TransactionException { + TransactionStatus tsb = copyTransactionStatus(ts); + try { + a.rollback(ts); + } + catch (Throwable t) { + System.err.println("Continuing to rollback tx despite this:" + t); + } + try { + b.rollback(tsb); + } + catch (Throwable t) { + System.err.println("Can't rollback tx" + t); + throw new TransactionException(t.getMessage(), t) {}; + } + } + +} diff --git a/src/test/java/org/springframework/persistence/test/Person.java b/src/test/java/org/springframework/persistence/test/Person.java new file mode 100644 index 000000000..e3e52ba7c --- /dev/null +++ b/src/test/java/org/springframework/persistence/test/Person.java @@ -0,0 +1,34 @@ +package org.springframework.persistence.test; + +import org.springframework.persistence.graph.GraphEntity; + +@GraphEntity +public class Person { + + private String name; + + private int age; + + public Person(String name, int age) { + this.name = name; + this.age = age; + } + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/src/test/java/org/springframework/persistence/test/graph/Neo4jGraphPersistenceTest.java b/src/test/java/org/springframework/persistence/test/graph/Neo4jGraphPersistenceTest.java new file mode 100644 index 000000000..9448891e6 --- /dev/null +++ b/src/test/java/org/springframework/persistence/test/graph/Neo4jGraphPersistenceTest.java @@ -0,0 +1,38 @@ +package org.springframework.persistence.test.graph; + +import junit.framework.Assert; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.neo4j.graphdb.GraphDatabaseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.persistence.test.Person; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +public class Neo4jGraphPersistenceTest { + + @Autowired + protected GraphDatabaseService graphDatabaseService; + + @Test + public void testGraphDatabaseServiceCreatedAndAutowired() { + Assert.assertNotNull( graphDatabaseService ); + } + + @Test + @Transactional + @Rollback(false) + public void testUserConstructor() { + int age = 39; + Person p = new Person("Rod", age); + Assert.assertEquals(p.getUnderlyingNode().getProperty("Person.name"), p.getName()); + Assert.assertEquals(age, p.getAge()); + } + +} diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties index 035716f13..0d19d218f 100644 --- a/src/test/resources/log4j.properties +++ b/src/test/resources/log4j.properties @@ -7,7 +7,7 @@ log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n log4j.appender.R=org.apache.log4j.RollingFileAppender -log4j.appender.R.File=application.log +log4j.appender.R.File=target/application.log log4j.appender.R.MaxFileSize=100KB # Keep one backup file diff --git a/src/test/resources/org/springframework/persistence/test/graph/Neo4jGraphPersistenceTest-context.xml b/src/test/resources/org/springframework/persistence/test/graph/Neo4jGraphPersistenceTest-context.xml new file mode 100644 index 000000000..cd4d53323 --- /dev/null +++ b/src/test/resources/org/springframework/persistence/test/graph/Neo4jGraphPersistenceTest-context.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +