【问题标题】:EntityManagerProvider is injected as nullEntityManagerProvider 被注入为 null
【发布时间】:2015-11-17 02:33:23
【问题描述】:

我使用的是忍者框架,utilizes JPA to access a database

我已经设法建立了一个连接并让它在一个示例控制器类中运行。

我想建模一个“userManager”,它在初始化时将所有当前用户从数据库加载到 java 映射中。

这样做时,我在调用 entitiyManagerProvider.get() 时遇到 java.lang.NullPointerException,因为 entitiyManagerProvider 设置为 null。

我不确定是什么导致了这个问题以及如何解决它,因为“UserManager”与我的(无问题的)测试控制器具有相同的注释。由于我对 ninja 或 JPA 没有任何经验,这可能是一个非常简单的修复,我只是忽略了,我将不胜感激。

这是“UserManager.java”的代码:

package model;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import com.google.inject.Inject;
import com.google.inject.Provider;
import dto.UserDTO;
import ninja.jpa.UnitOfWork;

public class UserManager {
    @Inject
    Provider<EntityManager> entitiyManagerProvider;

    private static UserManager instance;

    private Map<Integer, UserDTO> users = new HashMap<Integer, UserDTO>();

    //UserManager is a Singleton
    public static synchronized UserManager getInstance(){
        if (UserManager.instance == null){
            UserManager.instance = new UserManager();
        }
        return UserManager.instance;
    }

    private UserManager() {
        // load all existing users to map
        reloadUsersFromDb();

    }

    public int getAmountUsers(){
        return users.values().size();
    }


    /**
     * reloads ALL users in the map from the db
     */
    @UnitOfWork
    private void reloadUsersFromDb() {
        if (entitiyManagerProvider == null) {
            System.out.println("provider is null"); //this is printed
        } else {
            System.out.println("provider is NOT null"); //not printed
        }
        EntityManager entityManager = entitiyManagerProvider.get();
        //^-- causes null Pointer exception
        Query q = entityManager.createQuery("SELECT users FROM users");
        List<UserDTO> dbUsers = q.getResultList();

        int loadedUsers = 0;
        users.clear();
        for (UserDTO dbUser : dbUsers) {
            users.put(dbUser.getId(), dbUser);
            loadedUsers++;
        }

        System.out.println("loaded " + loadedUsers + "users from db to applicaton.");
    }

}

【问题讨论】:

    标签: java hibernate jpa nullpointerexception ninjaframework


    【解决方案1】:

    问题是注入永远不会对使用new 关键字直接创建的对象起作用。这就是您在getInstance() 方法中所做的事情。此外,您不应依赖构造函数中的注入值,因为它们仅在创建对象后才注入。

    要开启注入,UserManager 的实例必须由框架创建。控制器由框架自动创建,因此注入工作在那里。

    要修复您的代码,您可以从 UserManager 创建一个服务,从构造函数中删除对 reloadUsersFromDb 的调用,并将此方法标记为在启动时使用 @Start 运行,如 @987654321 中所述@

    【讨论】:

    • 似乎我无法启动任何带有 @UnitOfWork 注释的服务方法 - 你知道为什么会这样/如何解决它吗?
    • 你得到什么类型的异常?对于写入操作,您需要在事务中运行 - 除了 @UnitOfWork 之外,您还可以使用注释 @Transactional 来完成。或者,如果它与控制器一起使用,只需将控制器注入您的服务并从服务中调用其方法。所有详细信息都在 Ninja 文档页面上:ninjaframework.org/documentation/working_with_relational_dbs/…
    • 抱歉回复晚了。该函数在服务启动时被调用,但在具有 @Transactional 注释时未被调用。不知道到底是什么修复了它,但我重写了整个课程,现在它可以工作了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多