Spring-data跨店实体管理

我想在我的应用程序中一起使用Postgres,MongoDB和Neo4j.我能够将它们全部配置,但是现在我的每个POJO都支持我的graphNode以及aspectJ的文档.

有没有办法过滤掉哪些POJO仅由graphNodes支持,哪些只按文档?

我在单个请求中执行两次以上[sic!]时保存POJO有问题我可以在日志中看到mongo和neo4j都试图创建大量导致死锁之王的实例.

长话短说:

>有没有办法过滤数据映射以配置pojo“A”由RDBMS和图形(无文档)和pojo B按文档和图形(无RDBMS)进行映射
>是否存在基于跨商店弹簧数据的应用程序的样本,或多或少地涵盖了我的问题?
>为什么我可以逐个在控制器中保存两个pojo类实例但是在创建第三个实例时我会发现死锁?

[编辑]

我注意到了什么:

> Mongo aspectj builder支持@Entity注释POJO我不知道如何使用@Entity映射POJO for Hibernate而不是MongoDB
> Neo4j相关冻结仅在通过REST连接时发生,有时在3日有时发生,有时甚至根本不会发生.请参阅控制器启动它是如何完成的.我已经尝试了所有注释行但没有成功.
>事务管理器配置必须放在正确的位置,否则Neo4J配置验证器服务将失败.

[/编辑]

我用:

> Spring 3.0.5
> SpringRoo 1.4
> Spring-data 1.0
> Postgres 9.0 Hibernate 3.5.5
>远程Neo4j 1.3
>远程MongoDB 1.8.2
>所有数据库都在单个远程计算机上运行正常

[编辑]

POM切片:

<properties>
    <roo.version>1.1.4.RELEASE</roo.version>
    <spring.version>3.0.5.RELEASE</spring.version>
    <aspectj.version>1.6.11</aspectj.version>
    <slf4j.version>1.6.1</slf4j.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring-security.version>3.0.5.RELEASE</spring-security.version>
    <jackson.version>1.8.0</jackson.version>
    <spring.data.mongodb.version>1.0.0.M2</spring.data.mongodb.version>
    <spring.data.graph.version>1.0.0.RELEASE</spring.data.graph.version>
    <spring.data.commons.version>1.0.0.RELEASE</spring.data.commons.version>
</properties>
    ...
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-neo4j</artifactId>
        <version>${spring.data.graph.version}</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-mongodb-cross-store</artifactId>
        <version>${spring.data.mongodb.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-mongodb</artifactId>
        <version>${spring.data.mongodb.version}</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-neo4j-rest</artifactId>
        <version>${spring.data.graph.version}</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-commons-core</artifactId>
        <version>${spring.data.commons.version}</version>
        <scope>compile</scope>
    </dependency>

  ....
  <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.0</version>
            <dependencies>
                <!-- NB: You must use Maven 2.0.9 or above or these are ignored (see 
                    MNG-2972) -->
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjrt</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjtools</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <outxml>true</outxml>
                <aspectLibraries>
                    <aspectLibrary>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-aspects</artifactId>
                    </aspectLibrary>
                                            <aspectLibrary>
                        <groupId>org.springframework.data</groupId>
                        <artifactId>spring-data-neo4j</artifactId>
                    </aspectLibrary>
                    <aspectLibrary>
                        <groupId>org.springframework.data</groupId>
                        <artifactId>spring-data-mongodb-cross-store</artifactId>
                    </aspectLibrary>

                </aspectLibraries>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>

POJO:

@NodeEntity
@RooToString
@RooJavaBean
public class DElement {

@Indexed
private Long id;

@RelatedTo(direction=Direction.BOTH, elementClass=DRegion.class, type="SUBELEMENT_OF")
private Set<DElement> childElements = new HashSet<DElement>();

@Indexed(indexName = "delement-name", fulltext=true)
private String name;    



@Transactional
public void addChild(DElementchild child)
{
    this.childElements.add(child);
}

}

控制器(带加载):

    @Controller
    @RequestMapping(value="/DElements")
    public class DElementsController {

        DElementRepository DElementRepository;

        GraphDatabaseContext gdbc;

        @Autowired
        public DElementsController(DElementRepository DElementRepository, GraphDatabaseContext gdbc)
        {
            this.DElementRepository = DElementRepository;
            this.gdbc = gdbc;
            this.initElements();
        }

        @Transactional
        private void initElements()
        {
            try
            {
                DElementRepository.deleteall();

            } 
            catch (Exception e) {} finally{}

            //Transaction txn = gdbc.beginTx();

            referenceNode.createRelationshipTo(allElements.getPersistentState(), myRelation);

            DElement naElements = new DElement().persist();
            naElements.setName("1");
            allElements.addChild(naElements);

            DElement SAElements = new DElement().persist();
            SAElements.setName("2");
            allElements.addChild(SAElements);               

            DElement euElements = new DElement().persist();
            euElements.setName("3");
            allElements.addChild(euElements);

            DElement afElements = new DElement().persist();
            afElements.setName("4");    
            allElements.addChild(afElements);

            DElement asElements = new DElement().persist();
            asElements.setName("5");    
            allElements.addChild(asElements);

            DElement auElements = new DElement().persist();
            auElements.setName("6");
            allElements.addChild(auElements);


            //txn.success();
            //txn.finish();

        }
    }

applicationContext.xml中

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mongo="http://www.springframework.org/schema/data/mongo"
    xmlns:graph="http://www.springframework.org/schema/data/graph"
    xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/data/graph http://www.springframework.org/schema/data/graph/datagraph-1.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:property-placeholder location="classpath*:meta-inf/spring/*.properties" />
    <context:spring-configured />
    <bean id="validator"
        class="org.springframework.validation.beanvalidation.LocalValidatorfactorybean" />

    <context:component-scan base-package="com.foobar">
        <context:exclude-filter expression=".*_Roo_.*"
            type="regex" />
        <context:exclude-filter expression="org.springframework.stereotype.Controller"
            type="annotation" />
    </context:component-scan>
    <jee:jndi-lookup id="dataSource" jndi-name="jdbc/foobar" />




    <mongo:mongo host="${foobar.mongodb.addr}" port="27017" />
    <mongo:mapping-converter base-package="com.foobar.lib.model.mongo"/>

    <bean id="mongoTemplate" class="org.springframework.data.document.mongodb.MongoTemplate">
        <constructor-arg name="mongo" ref="mongo" />
        <constructor-arg name="databaseName" value="foobar" />
        <constructor-arg name="defaultCollectionName" value="basecoll" />
    </bean>

    <bean class="org.springframework.data.document.mongodb.MongoExceptionTranslator" />

    <!-- Mongo cross-store aspect config -->
    <bean
        class="org.springframework.data.persistence.document.mongo.Mongodocumentbacking"
        factory-method="aspectOf">
        <property name="changeSetPersister" ref="mongoChangeSetPersister" />
    </bean>
    <bean id="mongoChangeSetPersister"
        class="org.springframework.data.persistence.document.mongo.MongoChangeSetPersister">
        <property name="mongoTemplate" ref="mongoTemplate" />
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>


    <bean 
        id="graphDatabaseService" class="org.neo4j.kernel.EmbeddedGraphDatabase"
        destroy-method="shutdown" >
        <constructor-arg index="0" value="c:/neo4j/data/foobar" />
    </bean>
<!--  REST DOESNT WORK FOR THE MOMENT
    <bean id="graphDatabaseService" class="org.springframework.data.graph.neo4j.rest.support.RestGraphDatabase">
        <constructor-arg value="${foobar.neo4j.reststore}"/>        
    </bean> -->


<!--    <bean id="graphDatabaseContext" class="org.springframework.data.graph.neo4j.support.GraphDatabaseContext">
        <property name="graphDatabaseService" ref="graphDatabaseService"/>
    </bean> -->

    <graph:repositories base-package="com.foobar.data.repositories.neo4j" graph-database-context-ref="graphDatabaseContext"/>


    <graph:config graphDatabaseService="graphDatabaseService" entityManagerFactory="entityManagerFactory" />
    <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager" />    

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerfactorybean">     
        <property name="dataSource" ref="dataSource" />
    </bean> 
</beans>

[/编辑]

解决方法:

一些一般性评论.

当您想要使用Graph-JPA跨存储持久性时,您只需要将entityManagerFactory传递给Spring Data Graph.可以找到一个示例here.如果这样做,那么您还应该在POJO上启用要参与交叉存储设置的partial = true标志.

Spring数据图交叉存储和Spring数据MongoDB交叉存储在它们与JPA交互的方式上的工作方式不同,SDG在Graph POJO端工作时,持久化或加载它们(重新)连接到它们的JPA实体的实体(通过@Id字段) .

另一方面,Spring Data MongoDB使用AspectJ来扩充EntityManager的一些方法,以启动文档数据库的生命周期事件.

现在没有集成MongoDB和Neo4j的故事.但正如我们所说,两个项目的项目负责人住在同一个城市,并密切合作,我认为这应该是可行的.

如果您可以在我们的某个地方与github共享您的完整项目代码(也可能是私人仓库[我的github id是“jexp”,或者每封邮件或DropBox),那将是很棒的.
这样我们就可以直接挖掘它.

对你的问题:

> graph rdmbs是所有具有partial = true的实体,你必须在POJO上有@Entity注释
>我不确定如何正确配置mongo-cross-store持久性
>通常应该通过persistence.xml配置实体映射的存储?
>也许我们应该设计一种机制,说每个商店配置一个想要与EntityManager / JPA / RDMBS交互的persistence.xml
>也许这也可以通过为图形定义两个实体管理器,为mongo定义另一个实体管理器?
>你应该首先让它在neo4j的嵌入模式下运行,然后再查看远程服务器(REST)
>您应该将Spring Data Graph更新为1.1.M2,将Neo4j更新为1.4,将AspectJ更新为1.6.12.M1

请亲自联系,以便我们能够解决所有问题并找到一个好的解决方案.

相关文章

MongoTemplate 是Spring Data MongoDB 中的一个核心类,为 S...
笔者今天要分享的是一个项目重构过程中如何将数据库选型由原...
mongodb/mongoTemplate.upsert批量插入更新数据的实现
进入官网下载官网安装点击next勾选同意,点击next点击custom...
头歌 MongoDB实验——数据库基本操作
期末考试复习总结