Grails @Autowire in Java class not working

蓝咒 提交于 2019-12-04 06:35:53

问题


I have some Java code that I want to turn into a Bean that can be used within Grails controllers & services via dependency injection. The code is based on that here (which works fine when run as a standalone Java application).

Specifically, I have:

// WannabeABeanDB.java
package hello;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.kernel.impl.util.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.data.neo4j.core.GraphDatabase;

import java.io.File;

@Component
@Configuration
@EnableNeo4jRepositories(basePackages = "hello")
public class WannabeABeanDB extends Neo4jConfiguration {

    public WannabeABeanDB() {
        setBasePackage("hello");
    }

    @Bean
    GraphDatabaseService graphDatabaseService() {
        return new GraphDatabaseFactory().newEmbeddedDatabase("accessingdataneo4j.db");
    }

    @Autowired
    PersonRepository personRepository;

    @Autowired
    GraphDatabase graphDatabase;

    public String testThatWeCanAccessDatabase() throws Exception {
        Person greg = new Person("Greg");

        Transaction tx = graphDatabase.beginTx();
        try {
            personRepository.save(greg);
            greg = personRepository.findByName("Greg").toString();
            tx.success();
        } finally {
            tx.close();
        }
        return greg.name;

    }    
}



// Person.java
package hello;

import java.util.HashSet;
import java.util.Set;

import org.neo4j.graphdb.Direction;
import org.springframework.data.neo4j.annotation.Fetch;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelatedTo;

@NodeEntity
public class Person {

    @GraphId Long id;
    public String name;

    public Person() {}
    public Person(String name) { this.name = name; }

    public String toString() {
        return this.name;
    }
}



// PersonRepository.java
package hello;

import org.springframework.data.repository.CrudRepository;

public interface PersonRepository extends CrudRepository<Person, String> {    
    Person findByName(String name);    
}

So now I want to use from a controller:

// TestController.groovy
package hello

import hello.WannabeABeanDB

class TestController {

WannabeABeanDB graph

def index() { 
    render graph.test()
    }
}

I've set (within Config.groovy):

grails.spring.bean.packages = ['hello']

However, when I do a grails run-app, Grails crashes with a very long error message that says it can't work with a null database. I don't believe the @Autowire is being picked up for either PersonRepository or for graphDatabase.

So the question is, what more do I need to do to be able to write use Java code (within src/java) as a Bean within a Grails controller or service?


回答1:


-- Editing answer based on the sample code --

I suspect the issue is related to how component scanning works with Grails and Java code mixed together. It might also have to do with the order in which beans are created in this situation and proxying of classes behind the scenes.

I made the following changes to make this work:

  1. I went back to neo4j xml configuration and added a grails-app/conf/resources.xml with necessary neo4j configuration.

  2. Removed the @EnableNeo4jRepositories annotation from the class

  3. Took out statement from Config.groovy -- grails.spring.bean.packages = ['grailsSdn4j']

For others' reference, the neo4j configuration in resources.xml looks like this:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd">

    <context:spring-configured/>
    <context:annotation-config/>

    <neo4j:config storeDirectory="target/data/db" base-package="grailsSdn4j"/>

    <neo4j:repositories base-package="grailsSdn4j"/>
</beans>


来源:https://stackoverflow.com/questions/26894640/grails-autowire-in-java-class-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!