diff --git a/pom.xml b/pom.xml index 1ade39698..a89a1e9cc 100644 --- a/pom.xml +++ b/pom.xml @@ -162,6 +162,7 @@ spring-data-neo4j-examples/cineasts-rest spring-data-neo4j-examples/myrestaurants-social spring-data-neo4j-examples/todos + spring-data-neo4j-examples/backwardscompatibility diff --git a/spring-data-neo4j-aspects/src/test/resources/org/springframework/data/neo4j/aspects/support/Neo4jGraphPersistenceTest-context.xml b/spring-data-neo4j-aspects/src/test/resources/org/springframework/data/neo4j/aspects/support/Neo4jGraphPersistenceTest-context.xml index 7ee4111b7..eaec22b91 100644 --- a/spring-data-neo4j-aspects/src/test/resources/org/springframework/data/neo4j/aspects/support/Neo4jGraphPersistenceTest-context.xml +++ b/spring-data-neo4j-aspects/src/test/resources/org/springframework/data/neo4j/aspects/support/Neo4jGraphPersistenceTest-context.xml @@ -106,8 +106,8 @@ - - + + diff --git a/spring-data-neo4j-cross-store/src/main/java/org/springframework/data/neo4j/cross_store/config/CrossStoreNeo4jConfiguration.java b/spring-data-neo4j-cross-store/src/main/java/org/springframework/data/neo4j/cross_store/config/CrossStoreNeo4jConfiguration.java index f7f29fe8e..8994f2035 100644 --- a/spring-data-neo4j-cross-store/src/main/java/org/springframework/data/neo4j/cross_store/config/CrossStoreNeo4jConfiguration.java +++ b/spring-data-neo4j-cross-store/src/main/java/org/springframework/data/neo4j/cross_store/config/CrossStoreNeo4jConfiguration.java @@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.neo4j.aspects.config.Neo4jAspectConfiguration; +import org.springframework.data.neo4j.config.JtaTransactionManagerFactoryBean; import org.springframework.data.neo4j.cross_store.support.node.CrossStoreNodeDelegatingFieldAccessorFactory; import org.springframework.data.neo4j.cross_store.support.node.CrossStoreNodeEntityInstantiator; import org.springframework.data.neo4j.cross_store.support.node.CrossStoreNodeEntityStateFactory; @@ -68,14 +69,15 @@ public class CrossStoreNeo4jConfiguration extends Neo4jAspectConfiguration { } @Bean - public PlatformTransactionManager neo4jTransactionManager() { + public PlatformTransactionManager neo4jTransactionManager() throws Exception { + JtaTransactionManager jtaTm = new JtaTransactionManagerFactoryBean( getGraphDatabaseService() ).getObject(); + if (isUsingCrossStorePersistence()) { JpaTransactionManager jpaTm = new JpaTransactionManager(getEntityManagerFactory()); - JtaTransactionManager jtaTm = createJtaTransactionManager(); return new ChainedTransactionManager(jpaTm, jtaTm); } else { - return createJtaTransactionManager(); + return jtaTm; } } diff --git a/spring-data-neo4j-examples/backwardscompatibility/pom.xml b/spring-data-neo4j-examples/backwardscompatibility/pom.xml new file mode 100644 index 000000000..8286a8bf2 --- /dev/null +++ b/spring-data-neo4j-examples/backwardscompatibility/pom.xml @@ -0,0 +1,73 @@ + + + + spring-data-neo4j-dist + org.springframework.data + 2.1.0.BUILD-SNAPSHOT + + 4.0.0 + + backwardscompatibility + + + 3.0.7.RELEASE + 1.7 + + + + + org.neo4j + neo4j + ${neo4j.version} + + + org.springframework.data + spring-data-neo4j + 2.1.0.BUILD-SNAPSHOT + + + org.springframework + spring-test + ${spring.version} + test + + + commons-logging + commons-logging + + + + + + + + neo4j-snapshot-repository + Neo4j Maven 2 snapshot repository + http://m2.neo4j.org/snapshots + + true + + + false + + + + + + + 1.7 + + 1.7 + + + + 1.8-SNAPSHOT + + 1.8-SNAPSHOT + + + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/backwardscompatibility/src/test/java/backwardscompatibility/BackwardsCompatibilityTest.java b/spring-data-neo4j-examples/backwardscompatibility/src/test/java/backwardscompatibility/BackwardsCompatibilityTest.java new file mode 100644 index 000000000..0d24208bc --- /dev/null +++ b/spring-data-neo4j-examples/backwardscompatibility/src/test/java/backwardscompatibility/BackwardsCompatibilityTest.java @@ -0,0 +1,41 @@ +package backwardscompatibility; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.neo4j.graphdb.Node; +import org.neo4j.graphdb.Transaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.neo4j.support.Neo4jTemplate; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +@ContextConfiguration(locations = "classpath:/backwardscompatibility.xml") +@RunWith(SpringJUnit4ClassRunner.class) +@Transactional +public class BackwardsCompatibilityTest +{ + @Autowired + private Neo4jTemplate template; + + @Test + public void shouldBeBackwardsCompatible() throws Exception + { + Transaction transaction = template.getGraphDatabase().beginTx(); + + try + { + Node node = template.createNode(); + node.setProperty( "foo", "bar" ); + transaction.success(); + } + catch ( Exception e ) + { + transaction.failure(); + } + finally + { + transaction.finish(); + } + } +} diff --git a/spring-data-neo4j-examples/backwardscompatibility/src/test/resources/backwardscompatibility.xml b/spring-data-neo4j-examples/backwardscompatibility/src/test/resources/backwardscompatibility.xml new file mode 100644 index 000000000..14531011d --- /dev/null +++ b/spring-data-neo4j-examples/backwardscompatibility/src/test/resources/backwardscompatibility.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/JtaTransactionManagerFactoryBean.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/JtaTransactionManagerFactoryBean.java new file mode 100644 index 000000000..9b379e4cb --- /dev/null +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/JtaTransactionManagerFactoryBean.java @@ -0,0 +1,123 @@ +/** + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.neo4j.config; + +import javax.transaction.TransactionManager; +import javax.transaction.UserTransaction; + +import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.kernel.GraphDatabaseAPI; +import org.neo4j.kernel.impl.transaction.SpringTransactionManager; +import org.neo4j.kernel.impl.transaction.UserTransactionImpl; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.transaction.jta.JtaTransactionManager; +import org.springframework.transaction.jta.UserTransactionAdapter; + +public class JtaTransactionManagerFactoryBean implements FactoryBean +{ + private final JtaTransactionManager jtaTransactionManager; + + public JtaTransactionManagerFactoryBean( GraphDatabaseService gds ) throws Exception + { + jtaTransactionManager = create( gds ); + } + + @Override + public JtaTransactionManager getObject() throws Exception + { + return jtaTransactionManager; + } + + @Override + public Class getObjectType() + { + return JtaTransactionManager.class; + } + + @Override + public boolean isSingleton() + { + return true; + } + + private JtaTransactionManager create( GraphDatabaseService gds ) throws Exception + { + if ( !(gds instanceof GraphDatabaseAPI) ) + { + return createNullJtaTransactionManager(); + } + + try + { + return createJtaTransactionManager( gds ); + } + catch ( NoSuchMethodException e ) + { + return createJtaTransactionManagerForOnePointSeven( gds ); + } + } + + private JtaTransactionManager createNullJtaTransactionManager() + { + TransactionManager transactionManager = new NullTransactionManager(); + UserTransaction userTransaction = new UserTransactionAdapter( transactionManager ); + + return new JtaTransactionManager( userTransaction, transactionManager ); + } + + private JtaTransactionManager createJtaTransactionManagerForOnePointSeven( GraphDatabaseService gds ) throws Exception + { + TransactionManager transactionManager = createTransactionManagerForOnePointSeven( gds ); + UserTransaction userTransaction = createUserTransactionForOnePointSeven( gds ); + + return new JtaTransactionManager( userTransaction, transactionManager ); + } + + private JtaTransactionManager createJtaTransactionManager( GraphDatabaseService gds ) throws Exception + { + TransactionManager transactionManager = createTransactionManagerForOnePointEight( gds ); + UserTransaction userTransaction = createUserTransactionForOnePointEight( gds ); + + return new JtaTransactionManager( userTransaction, transactionManager ); + } + + private TransactionManager createTransactionManagerForOnePointSeven( GraphDatabaseService gds ) throws Exception + { + return createDynamically( SpringTransactionManager.class, GraphDatabaseService.class, gds ); + } + + private UserTransaction createUserTransactionForOnePointSeven( GraphDatabaseService gds ) throws Exception + { + TransactionManager txManager = ((GraphDatabaseAPI) gds).getTxManager(); + return createDynamically( UserTransactionImpl.class, TransactionManager.class, txManager ); + } + + private TransactionManager createTransactionManagerForOnePointEight( GraphDatabaseService gds ) throws Exception + { + return createDynamically( SpringTransactionManager.class, GraphDatabaseAPI.class, gds ); + } + + private UserTransaction createUserTransactionForOnePointEight( GraphDatabaseService gds ) throws Exception + { + return createDynamically( UserTransactionImpl.class, GraphDatabaseAPI.class, gds ); + } + + private T createDynamically( Class requiredClass, Class argumentClass, Object gds ) throws Exception + { + return requiredClass.getDeclaredConstructor( argumentClass ).newInstance( gds ); + } + +} diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/Neo4jConfiguration.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/Neo4jConfiguration.java index 93114d2c8..33e576074 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/Neo4jConfiguration.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/Neo4jConfiguration.java @@ -19,9 +19,6 @@ package org.springframework.data.neo4j.config; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Relationship; -import org.neo4j.kernel.GraphDatabaseAPI; -import org.neo4j.kernel.impl.transaction.SpringTransactionManager; -import org.neo4j.kernel.impl.transaction.UserTransactionImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; @@ -59,10 +56,6 @@ import org.springframework.data.neo4j.support.relationship.RelationshipEntitySta import org.springframework.data.neo4j.support.typerepresentation.ClassValueTypeInformationMapper; import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory; import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.jta.JtaTransactionManager; -import org.springframework.transaction.jta.UserTransactionAdapter; - -import javax.transaction.TransactionManager; import javax.validation.Validator; import static java.util.Arrays.asList; @@ -158,7 +151,7 @@ public abstract class Neo4jConfiguration { @Bean public TypeMapper relationshipTypeMapper() throws Exception { - return new DefaultTypeMapper(new TRSTypeAliasAccessor(relationshipTypeRepresentationStrategy()),asList(new ClassValueTypeInformationMapper())); + return new DefaultTypeMapper(new TRSTypeAliasAccessor(relationshipTypeRepresentationStrategy()),asList( new ClassValueTypeInformationMapper() )); } @Bean @@ -228,8 +221,8 @@ public abstract class Neo4jConfiguration { @Bean(name = {"neo4jTransactionManager","transactionManager"}) @Qualifier("neo4jTransactionManager") - public PlatformTransactionManager neo4jTransactionManager() { - return createJtaTransactionManager(); + public PlatformTransactionManager neo4jTransactionManager() throws Exception { + return new JtaTransactionManagerFactoryBean(getGraphDatabaseService()).getObject(); } @Bean @@ -237,21 +230,6 @@ public abstract class Neo4jConfiguration { return new IndexCreationMappingEventListener(neo4jTemplate()); } - protected JtaTransactionManager createJtaTransactionManager() { - JtaTransactionManager jtaTm = new JtaTransactionManager(); - final GraphDatabaseService gds = getGraphDatabaseService(); - if (gds instanceof GraphDatabaseAPI) { - final TransactionManager txManager = ((GraphDatabaseAPI) gds).getTxManager(); - jtaTm.setTransactionManager(new SpringTransactionManager(gds)); - jtaTm.setUserTransaction(new UserTransactionImpl(txManager)); - } else { - final NullTransactionManager tm = new NullTransactionManager(); - jtaTm.setTransactionManager(tm); - jtaTm.setUserTransaction(new UserTransactionAdapter(tm)); - } - return jtaTm; - } - @Bean @Autowired @DependsOn("graphDatabaseService") diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/config/TestTransactionManagerFactoryBean.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/config/TestTransactionManagerFactoryBean.java deleted file mode 100644 index a3a68e871..000000000 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/config/TestTransactionManagerFactoryBean.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Copyright 2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.data.neo4j.config; - -import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.kernel.AbstractGraphDatabase; -import org.neo4j.kernel.GraphDatabaseAPI; -import org.neo4j.kernel.impl.transaction.SpringTransactionManager; -import org.neo4j.kernel.impl.transaction.UserTransactionImpl; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.transaction.jta.JtaTransactionManager; -import org.springframework.transaction.jta.UserTransactionAdapter; - -import javax.transaction.TransactionManager; - -/** - * @author mh - * @since 09.04.11 - */ -public class TestTransactionManagerFactoryBean implements FactoryBean { - private GraphDatabaseService graphDatabaseService; - private JtaTransactionManager transactionManager; - - @Override - public JtaTransactionManager getObject() throws Exception { - return transactionManager; - } - - @Override - public Class getObjectType() { - return JtaTransactionManager.class; - } - - @Override - public boolean isSingleton() { - return true; - } - - private JtaTransactionManager createJtaTransactionManager(GraphDatabaseService gds) { - JtaTransactionManager jtaTm = new JtaTransactionManager(); - if (gds instanceof GraphDatabaseAPI) { - final TransactionManager txManager = ((GraphDatabaseAPI) gds).getTxManager(); - jtaTm.setTransactionManager(new SpringTransactionManager(gds)); - jtaTm.setUserTransaction(new UserTransactionImpl(txManager)); - } else { - final NullTransactionManager tm = new NullTransactionManager(); - jtaTm.setTransactionManager(tm); - jtaTm.setUserTransaction(new UserTransactionAdapter(tm)); - } - return jtaTm; - } - - public GraphDatabaseService getGraphDatabaseService() { - return graphDatabaseService; - } - - public void setGraphDatabaseService(GraphDatabaseService graphDatabaseService) { - this.graphDatabaseService = graphDatabaseService; - transactionManager = createJtaTransactionManager(graphDatabaseService); - } - -}