Spring Data Neo4J - 存储库不会改变@GraphId?

时间:2012-09-26 00:16:18

标签: spring neo4j spring-data-neo4j

我升级到Spring 3.1.2,Neo4J 1.8.RC1和SpringData 2.1.0.RC3,我遇到了以下问题。

在解释问题之前,这是我的应用程序上下文的一部分:

<!-- Neo4J -->
<neo4j:config storeDirectory="target/graph.db" entityManagerFactory="entityManagerFactory"/>
<neo4j:repositories base-package="***.repository"/>

<!-- H2 -->
<jdbc:embedded-database type="H2" id="accountDataSource">
    <jdbc:script location="classpath:scripts/schema.sql" separator=";"/>
</jdbc:embedded-database>


<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="accountDataSource" />
    <property name="packagesToScan" value="***.domain" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="generateDdl" value="false" />
            <property name="showSql" value="false" />
            <property name="databasePlatform" value="${database.dialect}" />
        </bean>
    </property>
</bean>

<!-- transactions -->
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<tx:annotation-driven mode="aspectj" />

我进行了一项非常基本的测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:devinlove-core.xml")
@Transactional
public class MascotRepositoryTest {

    @Autowired
    private MascotRepository mascotRepository;
    private Mascot mascot;

    @Before
    public void setup() {
        mascot = new Mascot();
        mascot.setName("Tux");
    }

    @Test
    public void when_inserting_then_retrievable() {
        assertThat(mascotRepository).isNotNull();
        mascotRepository.save(mascot);
        assertThat(mascot.getId()).isGreaterThan(0L);
    }
}

测试因NPE而失败。保存操作后,为什么吉祥物ID仍然为空?

MascotRepository的定义如下:

public interface MascotRepository extends GraphRepository<Mascot> {}

Mascot本身就是一个非常基本的NodeEntity:

@NodeEntity
@TypeAlias("mascot")
public class Mascot {
    @GraphId
    private Long id;

    @Indexed(indexType= FULLTEXT, indexName = "mascotSearch")
    private String name;

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Mascot{" +
            "id=" + id +
            ", name='" + name + '\'' +
            '}';
    }
}

我不知道这是否与问题相关,但我的一个NodeEntity是部分的,因此被AspectJ修改(添加基本的ActiveRecord方法)。您能否确认只有部分NodeEntities以这种方式修改而不是纯Neo4J实体?如果没有,它是否会导致与存储库发生冲突?

如果您有任何想法,请提前感谢! 罗尔夫

1 个答案:

答案 0 :(得分:0)

我认为transactionManager bean的正确定义是:

<bean id="jpaTransactionManager"
        class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="jtaTransactionManager"
        class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManager">
        <bean class="org.neo4j.kernel.impl.transaction.SpringTransactionManager">
            <constructor-arg ref="graphDatabaseService" />
        </bean>
    </property>
    <property name="userTransaction">
        <bean  class="org.neo4j.kernel.impl.transaction.UserTransactionImpl">
            <constructor-arg ref="graphDatabaseService" />
        </bean>
    </property>
</bean>
<bean id="transactionManager"
        class="org.springframework.data.neo4j.transaction.ChainedTransactionManager">
    <constructor-arg>
        <list>
            <ref bean="jpaTransactionManager"/>
            <ref bean="jtaTransactionManager"/>
        </list>
    </constructor-arg>
</bean>

<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>