5

Estoy usando la asignación de objeto/gráfico simple en Spring Data Neo4j 2.0, donde realizo operaciones de persistencia utilizando el marco de depósito de Spring Data. Estoy trabajando con los repositorios en lugar de trabajar con Neo4jTemplate. Inyecto los repositorios en mis controladores Spring Web MVC, y los controladores llaman directamente al repositorio. (Sin capa de servicio intermedio: mis operaciones son generalmente CRUD y consultas de buscador.)¿Manera correcta de realizar transacciones utilizando la asignación de objeto/gráfico simple de Spring Data Neo4j?

Cuando leo operaciones, no hay problemas. Pero cuando escribo operaciones, obtengo "NotInTransactionException". Según tengo entendido, las operaciones de lectura en Neo4j no requieren transacciones, pero sí operaciones de escritura.

¿Cuál es la mejor manera de hacer transacciones aquí, suponiendo que quiero seguir con el OGM simple? Quiero usar @Transactional, pero poner eso en las diversas interfaces de repositorio no funciona. Si presento un nivel de servicio intermedio entre los controladores y los repositorios y luego anoto los beans de servicio con @Transactional, entonces funciona, pero me pregunto si existe una forma más sencilla de hacerlo. Sin Spring Data, normalmente tendría acceso a las implementaciones de DAO (repositorio), así podría anotar los DAO concretos con @Transactional si quería evitar un nivel de servicio de paso a través. Con Spring Data, los repos se generan dinámicamente, por lo que no parece ser una opción.

+1

@Transactional en la Repository-Interfaces debería funcionar. –

Respuesta

6

En primer lugar, tenga en cuenta que tener DAO transaccionales no es generalmente una buena práctica. Pero si no tienes una capa de servicio, déjala en los DAO.

Luego, puede habilitar las transacciones declarativas. Así es como lo hice:

En primer lugar, definir una anotación llamada @GraphTransactional:

@Retention(RetentionPolicy.RUNTIME) 
@Transactional("neo4jTransactionManager") 
public @interface GraphTransactional { 

} 

Actualización: primavera-data-Neo4j han añadido una anotación por ejemplo, por lo que se puede reutilizar en lugar de crear una nueva uno: @Neo4jTransactional

Luego, en applicationContext.xml, tienen las siguientes (donde neo4jdb es su EmbeddedGraphDatabase):

<bean id="neo4jTransactionManagerService" 
    class="org.neo4j.kernel.impl.transaction.SpringTransactionManager"> 
    <constructor-arg ref="neo4jdb" /> 
</bean> 
<bean id="neo4jUserTransactionService" class="org.neo4j.kernel.impl.transaction.UserTransactionImpl"> 
    <constructor-arg ref="neo4jdb" /> 
</bean> 

<bean id="neo4jTransactionManager" 
    class="org.springframework.transaction.jta.JtaTransactionManager"> 
    <property name="transactionManager" ref="neo4jTransactionManagerService" /> 
    <property name="userTransaction" ref="neo4jUserTransactionService" /> 
</bean> 

<tx:annotation-driven transaction-manager="neo4jTransactionManager" /> 

Tenga en cuenta que si utiliza también otro administrador de transacciones, debe especificar order="2" para esta definición basada en anotaciones, y también tenga en cuenta que no tendrá confirmación en dos fases si tiene una método que se declara transaccional tanto sql como neo4j.

+4

ya existe @ Neo4jTransactional que hace exactamente eso. –

+3

y ya configura el administrador de transacciones de la manera que usted describe. –

+2

gracias, agregué una actualización. La anotación no estaba allí en versiones anteriores :) – Bozho

Cuestiones relacionadas