From cd4a51c60fb0a7892fbb62d32889f5c0059a0f3b Mon Sep 17 00:00:00 2001 From: Michael Hunger Date: Tue, 22 Feb 2011 15:16:15 +0100 Subject: [PATCH] Added external Transaction Manager Integration (via Spring configured JtaTransactionManager) moved TransactionManagers to transaction package provided JotmFactory Bean for Test removed Bundlor --- spring-data-graph-core/pom.xml | 8 - spring-data-graph-core/template.mf | 19 -- spring-data-graph-parent/pom.xml | 59 +++--- spring-data-neo4j-roo/pom.xml | 4 - spring-data-neo4j-roo/template.mf | 26 --- spring-data-neo4j/pom.xml | 20 +- .../ChainedTransactionManager.java | 2 +- .../DefaultSynchronizationManager.java | 2 +- .../neo4j/transaction/JotmFactoryBean.java | 171 ++++++++++++++++++ .../MultiTransactionStatus.java | 2 +- .../neo4j/transaction/SpringProvider.java | 41 +++++ .../neo4j/transaction/SpringServiceImpl.java | 102 +++++++++++ .../SynchronizationManager.java | 2 +- ...mpl.transaction.TransactionManagerProvider | 1 + .../ChainedTransactionManagerTest.java | 10 +- .../transaction/JOTMIntegrationTest.java | 109 +++++++++++ .../Neo4jGraphRecommendationTest-context.xml | 2 +- .../test/resources/spring-tx-text-context.xml | 37 ++++ spring-data-neo4j/template.mf | 30 --- src/docbkx/programming-model.xml | 52 ++++++ 20 files changed, 558 insertions(+), 141 deletions(-) delete mode 100644 spring-data-graph-core/template.mf delete mode 100644 spring-data-neo4j-roo/template.mf rename spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/{support => transaction}/ChainedTransactionManager.java (98%) rename spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/{support => transaction}/DefaultSynchronizationManager.java (91%) create mode 100644 spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/JotmFactoryBean.java rename spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/{support => transaction}/MultiTransactionStatus.java (98%) create mode 100644 spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/SpringProvider.java create mode 100644 spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/SpringServiceImpl.java rename spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/{support => transaction}/SynchronizationManager.java (76%) create mode 100644 spring-data-neo4j/src/main/resources/META-INF/services/org.neo4j.kernel.impl.transaction.TransactionManagerProvider rename spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/{support => transaction}/ChainedTransactionManagerTest.java (93%) create mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/transaction/JOTMIntegrationTest.java create mode 100644 spring-data-neo4j/src/test/resources/spring-tx-text-context.xml delete mode 100644 spring-data-neo4j/template.mf diff --git a/spring-data-graph-core/pom.xml b/spring-data-graph-core/pom.xml index b12332055..d07d14c07 100644 --- a/spring-data-graph-core/pom.xml +++ b/spring-data-graph-core/pom.xml @@ -85,12 +85,4 @@ - - - - com.springsource.bundlor - com.springsource.bundlor.maven - - - diff --git a/spring-data-graph-core/template.mf b/spring-data-graph-core/template.mf deleted file mode 100644 index d36e0b73b..000000000 --- a/spring-data-graph-core/template.mf +++ /dev/null @@ -1,19 +0,0 @@ -Bundle-SymbolicName: org.springframework.data.graph -Bundle-Name: Spring Data Graph -Bundle-Vendor: SpringSource -Bundle-ManifestVersion: 2 -Import-Package: - sun.reflect;version="0";resolution:=optional -Import-Template: - org.springframework.beans.*;version="[3.0.0, 4.0.0)", - org.springframework.core.*;version="[3.0.0, 4.0.0)", - org.springframework.dao.*;version="[3.0.0, 4.0.0)", - org.springframework.util.*;version="[3.0.0, 4.0.0)", - org.springframework.data.core.*;version="[1.0.0, 2.0.0)", - org.springframework.data.core.*;version="[1.0.0, 2.0.0)", - org.springframework.data.persistence.*;version="[1.0.0, 2.0.0)", - org.aopalliance.*;version="[1.0.0, 2.0.0)";resolution:=optional, - org.apache.commons.logging.*;version="[1.1.1, 2.0.0)", - org.w3c.dom.*;version="0" - - diff --git a/spring-data-graph-parent/pom.xml b/spring-data-graph-parent/pom.xml index 5e0b94e6e..c7f05f970 100644 --- a/spring-data-graph-parent/pom.xml +++ b/spring-data-graph-parent/pom.xml @@ -10,14 +10,14 @@ pom UTF-8 - 4.8.1 1.2.15 1.8.4 1.5.10 3.0.5.RELEASE 1.0.0.BUILD-SNAPSHOT - 1.3.M02 + 1.3.M02 + 1.6.11.BUILD-SNAPSHOT @@ -113,6 +113,11 @@ spring-tx ${org.springframework.version} + + org.springframework + spring-orm + ${org.springframework.version} + org.springframework spring-test @@ -220,6 +225,17 @@ test + + org.ow2.jotm + jotm-core + 2.1.9 + + + org.ow2.spec.ee + ow2-connector-1.5-spec + 1.0-M1 + + @@ -292,6 +308,7 @@ org.apache.maven.plugins maven-compiler-plugin + 2.3.2 1.6 1.6 @@ -303,6 +320,7 @@ org.apache.maven.plugins maven-surefire-plugin + 2.6 true @@ -317,7 +335,9 @@ + org.apache.maven.plugins maven-source-plugin + 2.0.4 attach-sources @@ -328,43 +348,10 @@ - - - - - com.springsource.bundlor - com.springsource.bundlor.maven - 1.0.0.RELEASE - - true - - - - bundlor - - bundlor - - - - - - - + repository.plugin.springsource.release SpringSource Maven Repository http://repository.springsource.com/maven/bundles/release diff --git a/spring-data-neo4j-roo/pom.xml b/spring-data-neo4j-roo/pom.xml index a7a7ca58a..2ee93c2fe 100644 --- a/spring-data-neo4j-roo/pom.xml +++ b/spring-data-neo4j-roo/pom.xml @@ -200,10 +200,6 @@ 1.6 - - com.springsource.bundlor - com.springsource.bundlor.maven - diff --git a/spring-data-neo4j-roo/template.mf b/spring-data-neo4j-roo/template.mf deleted file mode 100644 index b6e1739a9..000000000 --- a/spring-data-neo4j-roo/template.mf +++ /dev/null @@ -1,26 +0,0 @@ -Bundle-SymbolicName: org.springframework.data.neo4j.roo -Bundle-Name: Spring Data Neo4J Roo Support -Bundle-Vendor: SpringSource -Bundle-ManifestVersion: 2 -Import-Package: - sun.reflect;version="0";resolution:=optional -Import-Template: - org.springframework.beans.*;version="[3.0.0, 4.0.0)", - org.springframework.core.*;version="[3.0.0, 4.0.0)", - org.springframework.dao.*;version="[3.0.0, 4.0.0)", - org.springframework.jdbc.*;version="[3.0.0, 4.0.0)", - org.springframework.orm.*;version="[3.0.0, 4.0.0)", - org.springframework.transaction.*;version="[3.0.0, 4.0.0)", - org.springframework.util.*;version="[3.0.0, 4.0.0)", - org.springframework.data.core.*;version="[1.0.0, 2.0.0)", - org.springframework.data.core.*;version="[1.0.0, 2.0.0)", - org.springframework.data.annotation.*;version="[1.0.0, 2.0.0)", - org.springframework.data.graph.*;version="[1.0.0, 2.0.0)", - org.springframework.persistence.*;version="[1.0.0, 2.0.0)", - org.neo4j.*;version="0", - org.aspectj.*;version="[1.6.5, 2.0.0)", - org.apache.commons.logging.*;version="[1.1.1, 2.0.0)", - javax.annotation.*;version="0";resolution:=optional, - javax.persistence.*;version="[1.0.0, 3.0.0)";resolution:=optional, - javax.persistence.spi.*;version="[1.0.0, 3.0.0)";resolution:=optional, - javax.transaction.*;version="[1.0.1, 2.0.0)";resolution:=optional diff --git a/spring-data-neo4j/pom.xml b/spring-data-neo4j/pom.xml index 0f5a37e26..1b546243c 100644 --- a/spring-data-neo4j/pom.xml +++ b/spring-data-neo4j/pom.xml @@ -10,9 +10,6 @@ spring-data-neo4j jar Spring Data Neo4J Support - - 1.6.11.BUILD-SNAPSHOT - @@ -27,7 +24,6 @@ org.springframework spring-orm - ${org.springframework.version} @@ -44,6 +40,18 @@ spring-data-graph-core + + + org.ow2.jotm + jotm-core + provided + + + org.ow2.spec.ee + ow2-connector-1.5-spec + provided + + org.slf4j @@ -216,10 +224,6 @@ 1.6 - - com.springsource.bundlor - com.springsource.bundlor.maven - diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/ChainedTransactionManager.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/ChainedTransactionManager.java similarity index 98% rename from spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/ChainedTransactionManager.java rename to spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/ChainedTransactionManager.java index 77ae8a641..2d86821d1 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/ChainedTransactionManager.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/ChainedTransactionManager.java @@ -1,4 +1,4 @@ -package org.springframework.data.graph.neo4j.support; +package org.springframework.data.graph.neo4j.transaction; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/DefaultSynchronizationManager.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/DefaultSynchronizationManager.java similarity index 91% rename from spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/DefaultSynchronizationManager.java rename to spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/DefaultSynchronizationManager.java index 4a7eddd0e..5ba849bef 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/DefaultSynchronizationManager.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/DefaultSynchronizationManager.java @@ -1,4 +1,4 @@ -package org.springframework.data.graph.neo4j.support; +package org.springframework.data.graph.neo4j.transaction; import org.springframework.transaction.support.TransactionSynchronizationManager; diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/JotmFactoryBean.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/JotmFactoryBean.java new file mode 100644 index 000000000..64b822148 --- /dev/null +++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/JotmFactoryBean.java @@ -0,0 +1,171 @@ +/* + * Copyright 2010 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.graph.neo4j.transaction; + +import org.objectweb.jotm.Current; +import org.objectweb.jotm.Jotm; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; + +import javax.naming.NamingException; +import javax.transaction.SystemException; + +/** + * FactoryBean that retrieves the JTA UserTransaction/TransactionManager for + * ObjectWeb's JOTM. Will retrieve + * an already active JOTM instance if found (e.g. if running in JOnAS), + * else create a new local JOTM instance. + *

+ *

With JOTM, the same object implements both the + * {@link javax.transaction.UserTransaction} and the + * {@link javax.transaction.TransactionManager} interface, + * as returned by this FactoryBean. + *

+ *

A local JOTM instance is well-suited for working in conjunction with + * ObjectWeb's XAPool, e.g. with bean + * definitions like the following: + *

+ *

+ * <bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/>
+ * 

+ * <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> + * <property name="userTransaction" ref="jotm"/> + * </bean> + *

+ * <bean id="innerDataSource" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown"> + * <property name="transactionManager" ref="jotm"/> + * <property name="driverName" value="..."/> + * <property name="url" value="..."/> + * <property name="user" value="..."/> + * <property name="password" value="..."/> + * </bean> + *

+ * <bean id="dataSource" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown"> + * <property name="dataSource" ref="innerDataSource"/> + * <property name="user" value="..."/> + * <property name="password" value="..."/> + * <property name="maxSize" value="..."/> + * </bean>

+ *

+ * Note that Spring's {@link org.springframework.transaction.jta.JtaTransactionManager} will automatically detect + * that the passed-in UserTransaction reference also implements the + * TransactionManager interface. Hence, it is not necessary to specify a + * separate reference for JtaTransactionManager's "transactionManager" property. + *

+ *

Implementation note: This FactoryBean uses JOTM's static access method + * to obtain the JOTM {@link org.objectweb.jotm.Current} object, which + * implements both the UserTransaction and the TransactionManager interface, + * as mentioned above. + * + * @author Juergen Hoeller + * @see org.springframework.transaction.jta.JtaTransactionManager#setUserTransaction + * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager + * @see org.objectweb.jotm.Current + * @since 21.01.2004 + */ +public class JotmFactoryBean implements FactoryBean, DisposableBean, InitializingBean { + + private Current jotmCurrent; + + private Jotm jotm; + private String jotmHome; + private Integer defaultTimeout; + private Boolean transactionRecovery; + + + /** + * Set the default transaction timeout for the JOTM instance. + *

Should only be called for a local JOTM instance, + * not when accessing an existing (shared) JOTM instance. + */ + public void setDefaultTimeout(int defaultTimeout) { + this.defaultTimeout = defaultTimeout; + } + + + public void setTransactionRecovery(boolean transactionRecovery) throws SystemException { + this.transactionRecovery = transactionRecovery; + } + + /** + * @param jotmHome the directory that contains conf/jotm.properties + */ + public void setJotmHome(String jotmHome) { + this.jotmHome = jotmHome; + } + + @Override + public void afterPropertiesSet() throws Exception { + createJotm(); + } + + private void createJotm() throws NamingException, SystemException { + if (jotmHome!=null) { + System.setProperty("jotm.home",jotmHome); + } + // Check for already active JOTM instance. + this.jotmCurrent = Current.getCurrent(); + + // If none found, create new local JOTM instance. + if (this.jotmCurrent == null) { + // Only for use within the current Spring context: + // local, not bound to registry. + this.jotm = new Jotm(true, false); + this.jotmCurrent = Current.getCurrent(); + } + if (defaultTimeout!=null) { + this.jotmCurrent.setDefaultTimeout(defaultTimeout); + } + if (transactionRecovery!=null) { + this.jotmCurrent.setTransactionRecovery(transactionRecovery); + } + } + + /** + * Return the JOTM instance created by this factory bean, if any. + * Will be null if an already active JOTM instance is used. + *

Application code should never need to access this. + */ + public Jotm getJotm() { + return this.jotm; + } + + + public Object getObject() { + return this.jotmCurrent; + } + + public Class getObjectType() { + return this.jotmCurrent.getClass(); + } + + public boolean isSingleton() { + return true; + } + + + /** + * Stop the local JOTM instance, if created by this FactoryBean. + */ + public void destroy() { + if (this.jotm != null) { + this.jotm.stop(); + } + } + +} diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/MultiTransactionStatus.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/MultiTransactionStatus.java similarity index 98% rename from spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/MultiTransactionStatus.java rename to spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/MultiTransactionStatus.java index 4ecac2018..10306a1ee 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/MultiTransactionStatus.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/MultiTransactionStatus.java @@ -1,4 +1,4 @@ -package org.springframework.data.graph.neo4j.support; +package org.springframework.data.graph.neo4j.transaction; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/SpringProvider.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/SpringProvider.java new file mode 100644 index 000000000..cf51c57ad --- /dev/null +++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/SpringProvider.java @@ -0,0 +1,41 @@ +/* + * Copyright 2010 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.graph.neo4j.transaction; + +import org.neo4j.helpers.Service; +import org.neo4j.kernel.impl.core.KernelPanicEventGenerator; +import org.neo4j.kernel.impl.transaction.AbstractTransactionManager; +import org.neo4j.kernel.impl.transaction.TransactionManagerProvider; +import org.neo4j.kernel.impl.transaction.TxFinishHook; +import org.springframework.beans.factory.annotation.Configurable; + +@Configurable +@Service.Implementation( TransactionManagerProvider.class ) +public class SpringProvider extends TransactionManagerProvider +{ + public SpringProvider() + { + super( "spring-jta" ); + } + + @Override + protected AbstractTransactionManager loadTransactionManager( String txLogDir, + KernelPanicEventGenerator kpe, TxFinishHook rollbackHook ) + { + return new SpringServiceImpl(); + } +} diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/SpringServiceImpl.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/SpringServiceImpl.java new file mode 100644 index 000000000..f416fd874 --- /dev/null +++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/SpringServiceImpl.java @@ -0,0 +1,102 @@ +/* + * Copyright 2010 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.graph.neo4j.transaction; + +import org.neo4j.kernel.impl.transaction.AbstractTransactionManager; +import org.neo4j.kernel.impl.transaction.XaDataSourceManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.transaction.jta.JtaTransactionManager; + +import javax.transaction.*; + +/** + * @author Chris Gioran + */ +@Configurable +class SpringServiceImpl extends AbstractTransactionManager +{ + @Autowired + private JtaTransactionManager jtaTransactionManager; + + private TransactionManager delegate; + + SpringServiceImpl() + { + } + + @Override + public void init( XaDataSourceManager xaDsManager ) + { + delegate = jtaTransactionManager.getTransactionManager(); + } + + public void begin() throws NotSupportedException, SystemException + { + delegate.begin(); + } + + public void commit() throws RollbackException, HeuristicMixedException, + HeuristicRollbackException, SecurityException, + IllegalStateException, SystemException + { + delegate.commit(); + } + + public int getStatus() throws SystemException + { + return delegate.getStatus(); + } + + public Transaction getTransaction() throws SystemException + { + return delegate.getTransaction(); + } + + public void resume( Transaction tobj ) throws InvalidTransactionException, + IllegalStateException, SystemException + { + delegate.resume( tobj ); + } + + public void rollback() throws IllegalStateException, SecurityException, + SystemException + { + delegate.rollback(); + } + + public void setRollbackOnly() throws IllegalStateException, SystemException + { + delegate.setRollbackOnly(); + } + + public void setTransactionTimeout( int seconds ) throws SystemException + { + delegate.setTransactionTimeout( seconds ); + } + + public Transaction suspend() throws SystemException + { + return delegate.suspend(); + } + + @Override + public void stop() + { + // Currently a no-op + } +} diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/SynchronizationManager.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/SynchronizationManager.java similarity index 76% rename from spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/SynchronizationManager.java rename to spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/SynchronizationManager.java index 1bbc2f9d9..063cc3279 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/SynchronizationManager.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/transaction/SynchronizationManager.java @@ -1,4 +1,4 @@ -package org.springframework.data.graph.neo4j.support; +package org.springframework.data.graph.neo4j.transaction; /** * @author mh diff --git a/spring-data-neo4j/src/main/resources/META-INF/services/org.neo4j.kernel.impl.transaction.TransactionManagerProvider b/spring-data-neo4j/src/main/resources/META-INF/services/org.neo4j.kernel.impl.transaction.TransactionManagerProvider new file mode 100644 index 000000000..540a6813d --- /dev/null +++ b/spring-data-neo4j/src/main/resources/META-INF/services/org.neo4j.kernel.impl.transaction.TransactionManagerProvider @@ -0,0 +1 @@ +org.springframework.data.graph.neo4j.transaction.SpringProvider diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/ChainedTransactionManagerTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/transaction/ChainedTransactionManagerTest.java similarity index 93% rename from spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/ChainedTransactionManagerTest.java rename to spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/transaction/ChainedTransactionManagerTest.java index 416768cc3..497c4ac5c 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/support/ChainedTransactionManagerTest.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/transaction/ChainedTransactionManagerTest.java @@ -1,4 +1,4 @@ -package org.springframework.data.graph.neo4j.support; +package org.springframework.data.graph.neo4j.transaction; import org.hamcrest.Description; import org.hamcrest.Factory; @@ -9,10 +9,10 @@ import org.springframework.transaction.support.DefaultTransactionDefinition; import static junit.framework.Assert.*; import static org.junit.Assert.assertThat; -import static org.springframework.data.graph.neo4j.support.ChainedTransactionManagerTest.TestPlatformTransactionManager.createFailingTransactionManager; -import static org.springframework.data.graph.neo4j.support.ChainedTransactionManagerTest.TestPlatformTransactionManager.createNonFailingTransactionManager; -import static org.springframework.data.graph.neo4j.support.ChainedTransactionManagerTest.TransactionManagerMatcher.isCommitted; -import static org.springframework.data.graph.neo4j.support.ChainedTransactionManagerTest.TransactionManagerMatcher.wasRolledback; +import static org.springframework.data.graph.neo4j.transaction.ChainedTransactionManagerTest.TestPlatformTransactionManager.createFailingTransactionManager; +import static org.springframework.data.graph.neo4j.transaction.ChainedTransactionManagerTest.TestPlatformTransactionManager.createNonFailingTransactionManager; +import static org.springframework.data.graph.neo4j.transaction.ChainedTransactionManagerTest.TransactionManagerMatcher.isCommitted; +import static org.springframework.data.graph.neo4j.transaction.ChainedTransactionManagerTest.TransactionManagerMatcher.wasRolledback; import static org.springframework.transaction.HeuristicCompletionException.getStateString; /** diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/transaction/JOTMIntegrationTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/transaction/JOTMIntegrationTest.java new file mode 100644 index 000000000..2a7eac265 --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/transaction/JOTMIntegrationTest.java @@ -0,0 +1,109 @@ +package org.springframework.data.graph.neo4j.transaction; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.graphdb.Node; +import org.neo4j.graphdb.NotFoundException; +import org.neo4j.graphdb.index.IndexHits; +import org.neo4j.kernel.Config; +import org.neo4j.kernel.EmbeddedGraphDatabase; +import org.objectweb.jotm.Current; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.transaction.jta.JtaTransactionManager; +import org.springframework.transaction.jta.ManagedTransactionAdapter; + +import javax.transaction.NotSupportedException; +import javax.transaction.SystemException; +import javax.transaction.Transaction; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +/** + * @author mh + * @since 21.02.11 + */ + +public class JOTMIntegrationTest { + private ClassPathXmlApplicationContext ctx; + private GraphDatabaseService gds; + + @Before + public void setUp() throws Exception { + ctx = new ClassPathXmlApplicationContext("classpath:spring-tx-text-context.xml"); + gds = ctx.getBean(GraphDatabaseService.class); + } + + @After + public void tearDown() throws Exception { + if (ctx != null) ctx.close(); + } + + @Test + public void createdNodeShouldBeFoundAfterCommit() throws Exception { + org.neo4j.graphdb.Transaction transaction = gds.beginTx(); + Node node = null; + try { + node = gds.createNode(); + assertNotNull(node); + transaction.success(); + } finally { + transaction.finish(); + } + Node readBackOutsideOfTx = gds.getNodeById(node.getId()); + assertEquals(node, readBackOutsideOfTx); + try { + transaction = gds.beginTx(); + Node readBackInsideOfTx = gds.getNodeById(node.getId()); + assertEquals(node, readBackInsideOfTx); + transaction.success(); + } finally { + transaction.finish(); + } + } + + @Test + public void indexedNodeShouldBeFound() throws Exception { + org.neo4j.graphdb.Transaction transaction = gds.beginTx(); + Node node = null; + try { + node = gds.createNode(); + gds.index().forNodes("node").add(node, "name", "value"); + transaction.success(); + } finally { + transaction.finish(); + } + Node retrievedNode = gds.index().forNodes("node").get("name", "value").getSingle(); + assertEquals(node,retrievedNode); + } + + @Test(expected = NotFoundException.class) + public void createdNodeShouldBeNotAvailableAfterRollback() throws Exception { + org.neo4j.graphdb.Transaction tx = gds.beginTx(); + long nodeId=0; + try { + Node node = gds.createNode(); + nodeId = node.getId(); + tx.failure(); + } finally { + tx.finish(); + } + gds.getNodeById(nodeId); + } + + @Test + public void databaseConfiguredWithSpringJtaShouldUseJtaTransactionManager() throws SystemException, NotSupportedException { + Map config = ((EmbeddedGraphDatabase) gds).getConfig().getParams(); + assertEquals("spring-jta", config.get(Config.TXMANAGER_IMPLEMENTATION)); + + JtaTransactionManager tm = ctx.getBean("transactionManager", JtaTransactionManager.class); + Transaction transaction = tm.createTransaction("jotm", 1000); + + assertEquals(ManagedTransactionAdapter.class, transaction.getClass()); + assertEquals(Current.class, ((ManagedTransactionAdapter) transaction).getTransactionManager().getClass()); + } +} diff --git a/spring-data-neo4j/src/test/resources/org/springframework/data/graph/neo4j/partial/Neo4jGraphRecommendationTest-context.xml b/spring-data-neo4j/src/test/resources/org/springframework/data/graph/neo4j/partial/Neo4jGraphRecommendationTest-context.xml index 7b39e520f..7569fb632 100644 --- a/spring-data-neo4j/src/test/resources/org/springframework/data/graph/neo4j/partial/Neo4jGraphRecommendationTest-context.xml +++ b/spring-data-neo4j/src/test/resources/org/springframework/data/graph/neo4j/partial/Neo4jGraphRecommendationTest-context.xml @@ -137,7 +137,7 @@ - + diff --git a/spring-data-neo4j/src/test/resources/spring-tx-text-context.xml b/spring-data-neo4j/src/test/resources/spring-tx-text-context.xml new file mode 100644 index 000000000..abf7dccf6 --- /dev/null +++ b/spring-data-neo4j/src/test/resources/spring-tx-text-context.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j/template.mf b/spring-data-neo4j/template.mf deleted file mode 100644 index c3e5684c3..000000000 --- a/spring-data-neo4j/template.mf +++ /dev/null @@ -1,30 +0,0 @@ -Bundle-SymbolicName: org.springframework.data.neo4j -Bundle-Name: Spring Data Neo4J -Bundle-Vendor: SpringSource -Bundle-ManifestVersion: 2 -Import-Package: - sun.reflect;version="0";resolution:=optional -Import-Template: - org.springframework.beans.*;version="[3.0.0, 4.0.0)", - org.springframework.context.*;version="[3.0.0, 4.0.0)", - org.springframework.core.*;version="[3.0.0, 4.0.0)", - org.springframework.dao.*;version="[3.0.0, 4.0.0)", - org.springframework.jdbc.*;version="[3.0.0, 4.0.0)", - org.springframework.orm.*;version="[3.0.0, 4.0.0)", - org.springframework.transaction.*;version="[3.0.0, 4.0.0)", - org.springframework.util.*;version="[3.0.0, 4.0.0)", - org.springframework.data.core.*;version="[1.0.0, 2.0.0)", - org.springframework.data.core.*;version="[1.0.0, 2.0.0)", - org.springframework.data.annotation.*;version="[1.0.0, 2.0.0)", - org.springframework.persistence.*;version="[1.0.0, 2.0.0)", - org.springframework.data.graph.*;version="0", - org.neo4j.*;version="0", - org.w3c.dom.*;version="0", - org.aspectj.*;version="[1.6.5, 2.0.0)", - org.apache.commons.logging.*;version="[1.1.1, 2.0.0)", - org.apache.lucene.*;version="0", - javax.validation.*;version="0";resolution:=optional, - javax.annotation.*;version="0";resolution:=optional, - javax.persistence.*;version="[1.0.0, 3.0.0)";resolution:=optional, - javax.persistence.spi.*;version="[1.0.0, 3.0.0)";resolution:=optional, - javax.transaction.*;version="[1.0.1, 2.0.0)";resolution:=optional diff --git a/src/docbkx/programming-model.xml b/src/docbkx/programming-model.xml index e32dd16ef..9154413d3 100644 --- a/src/docbkx/programming-model.xml +++ b/src/docbkx/programming-model.xml @@ -324,6 +324,58 @@ for (Person person : finder.findAllByProperyValue("occupation","developer")) { trainInSpringData(developer.projectTo(Trainee.class)); } } +]]> +

+ Dynamic Typing - Projection to unrelated, fitting types + + As the underlying data model of a graph database doesn't imply and enforce strict type constraints like a relational + model does, it offers much more flexibility on how to model your domain classes and which of those to use in different + contexts. + + + For instance an order can be used in these contexts: customer, procurement, logistics, billing, fulfillment and many more. + Each of those contexts requires its distinct set of attributes and operations. As Java doesn't support mixins one would put + the sum of all of those into the entity class and thereby making it very big, brittle and hard to understand. + Being able to take a basic order and project it to a different (not related in the inheritance hierarchy or even an interface) + order type that is valid in the current context and only offers the attributes and methods needed here would be very benefitial. + + DATAGRAPH offers initial support for projecting node and relationship entities to different target types. + All instances of this projected entity share the same backing node or relationship, so data changes are reflected + immediately. + + + This could for instance also be used to handle nodes of a traversal with a unified (simpler) type (e.g. for + reporting or auditing) and only project them to a concrete, more functional target type when the business + logic requires it. + + trainings; +} + +for (Person person : finder.findAllByProperyValue("occupation","developer")) { + Developer developer=person.projectTo(Developer.class) + if (developer.isJavaDeveloper()) { + trainInSpringData(developer.projectTo(Trainee.class)); + } +} +]]> + +
+
+ Neo4jTemplate + +