Spring-data跨店实体管理

时间:2011-07-18 03:32:36

标签: spring mongodb neo4j spring-data-graph

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

有没有办法过滤掉仅由graphNodes支持的POJO以及仅按文档支持哪些POJO?

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

故事很长:

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

    我注意到了什么:

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

      我用:

      1. Spring 3.0.5
      2. SpringRoo 1.4
      3. Spring-data 1.0
      4. Postgres 9.0 + Hibernate 3.5.5
      5. 远程Neo4j 1.3
      6. 远程MongoDB 1.8.2
      7. 所有数据库都在单个远程计算机上,工作正常
      8. [编辑]

        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>
        

        [/编辑]

1 个答案:

答案 0 :(得分:4)

一些一般性评论。

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

Spring Data Graph交叉存储和Spring Data MongoDB交叉存储在与JPA交互时的工作方式不同,当持久化或加载它们(重新)连接到JPA实体的实体时,SDG在Graph POJO端工作(通过@ 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

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