依赖注入和JPA和Hibernate

时间:2016-02-27 00:22:13

标签: hibernate jpa dependency-injection jboss cdi

第1类:Repository.java:

@ApplicationScoped
public class Repository {

    @Inject
    private EntityManager em;

    public Term findById(Long id) {
        return em.find(Term.class, id);
    }
}

第2课:Word.java

@Named
@RequestScoped
public class Word {

    @Inject
    private Logger log;

    @Inject
    private Repository repository;

    private Term term;

    public Word() {

    }

    public Word(Long id) {

        try{
            term = this.findTermById(id);       
        }catch(Exception e) {
            e.printStackTrace();
        }
    }

    @Produces
    @Named
    public Term getTerm() {

        return term;
    }

    public Term findTermById(Long id) {

        Term term = repository.findById(id);

        if(term==null) {
            log.info("Can't find this word from database: " + term);
        }

        return term;
    }
}

第3课:Resources.java

public class Resources {
    @Produces
    @PersistenceContext
    private EntityManager em;

    @Produces
    public Logger produceLog(InjectionPoint injectionPoint) {
        return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
    }

    @Produces
    @RequestScoped
    public FacesContext produceFacesContext() {
        return FacesContext.getCurrentInstance();
    }
}

这两个类的问题在于,在运行服务器时,它会在行处抛出NullPointerException:

Term term = repository.findById(id);

这意味着注入对象'repository'失败,因为调试显示“repository = null”。

@Inject
private Repository repository;

为什么注射不成功?谢谢。

2 个答案:

答案 0 :(得分:1)

正如@Geinmachi所说,你在构造函数中调用它,但是你没有在构造函数中注入它,而是在字段级别上,直到@PostConstruct才初始化它。

您可以使用构造函数注入将存储库作为参数注入,但您不应该手动实例化Word,而是通过CDI注入。

@Inject
public Word(Repository repo) {
    this.repo = repo;
}

一般情况下,构造函数永远不应该执行操作(比如你正在进行的数据库查找),这是非常糟糕的做法,因为没有人知道来自外部的行为加上你在@Inject期间不会有事务。此外,您不应手动实例化CDI bean,因为它们的生命周期由CDI管理,并且旨在通过@Inject使用。

此外,通过使用Applicationscoped实体管理器,您将遇到并发问题,它应该是请求编写的。

答案 1 :(得分:0)

你没有完整的堆栈跟踪吗?我认为NullPointerException可能来自您的Repository bean中的5*cos(4x+2)为空。

CDI没有看到你的类资源,因为它没有定义bean。 (据我所知,从代码中可以看出。)