spring-data-neo4j 与 Autowired 冲突

spring-data-neo4j conflict with Autowired

所以我有一个使用 spring-data-neo4j 的项目,遇到了一个难解的问题。 我对 spring-neo4j 使用 java 配置,Neo4jConfig.java:

@Configuration
@EnableNeo4jRepositories(basePackages = "org.neo4j.example.repository")
@EnableTransactionManagement
public class Neo4jConfig extends Neo4jConfiguration {

    @Bean
    public SessionFactory getSessionFactory() {
        // with domain entity base package(s)
        return new SessionFactory("org.neo4j.example.domain");
    }

    // needed for session in view in web-applications
    @Bean
    @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
    public Session getSession() throws Exception {
        return super.getSession();
    }

}

我有一个 DAO 和一个实现,BeanDaoImpl.java:

@Repository
public class BeanDaoImpl implements BeanDao {
    public String getStr() {
        return "from BeanImpl";
    }
}

然后我有一个使用 DaoImpl 的服务,注意自动装配的是 BeanDaoImpl,而不是 BeanDao:

@Service
public class MyBeanService {
    @Autowired
    private BeanDaoImpl daoImpl;


    public String getServiceString(){
        return daoImpl.getStr();
    }
}

这是我的应用-context.xml:

    <context:component-scan base-package="com.springconflict" />

版本是springframework 4.2.5,spring-data-neo4j 4.1.11,看来spring-data-neo4j和spring兼容4.2.5;

这里是编译错误信息:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.springconflict.dao.impl.BeanDaoImpl com.springconflict.service.MyBeanService.daoImpl; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.springconflict.dao.impl.BeanDaoImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

可能性是我删除 Neo4jConfig 或使用 @Autowired BeanDao 测试可以通过。另外,我用的是普通的@Configuration class,测试还是通过了,所以问题可能在Neo4jConfiguration,有人能告诉我为什么以及如何解决这个问题吗? 我无法在实际项目中将 @Autowired BeanDaoImpl 更改为 @Autowired BeanDao

all code are in here

TL;DR 答案:在 Neo4jConfig 中定义以下附加 bean,从而覆盖 SDN 4.x 的默认实例 PersistenceExceptionTranslationPostProcessor

@Bean
PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor() {
    PersistenceExceptionTranslationPostProcessor p = new PersistenceExceptionTranslationPostProcessor();
    p.setProxyTargetClass(true);
    return p;
}

长答案:Spring Data Neo4j 使用 Springs PersistenceExceptionTranslationPostProcessor 将 Neo4j OGM 异常重新映射为 Spring Data 异常。这些处理器应用于 @Repository 类型的所有组件。

所以 post 处理器现在形成了围绕您的 BeanDoaImpl 的代理,因此它基本上就像另一个 class。如果您使用该接口,则效果很好,但如果您想将 bean 分配给具体 class.

,则效果不佳

Spring 可以全局配置以创建子 classes 而不是基于标准 Java 接口的代理(它通过使用 CGLIB 实现),但默认情况下不启用并且在 Spring 4.2.x 和 Spring Data Neo4j 4.2.x 的情况下无论如何都无关紧要,因为上面的 post 处理器独立于该机制.

用一个明确配置的替换它可以解决您的问题。

不过,从架构的角度(或干净的代码方面)来看,注入接口而不是具体的 class 会更好。

如果我能帮到你,请告诉我:)