EntityManagerProvider 被注入为 null
EntityManagerProvider is injected as null
我正在使用忍者框架,utilizes JPA to access a database。
我已经成功地建立了连接并在示例控制器 运行 中获得了它 class。
我想建模一个 "userManager",它在初始化时将所有当前用户从数据库加载到一个 java 映射中。
这样做时,我在调用 entitiyManagerProvider.get() 时遇到 java.lang.NullPointerException,因为 entitiyManagerProvider 设置为 null。
我不确定是什么导致了这个问题以及如何解决它,因为 "UserManager" 与我的(无问题的)测试控制器具有相同的注释。由于我对忍者或 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.");
}
}
问题在于注入永远无法处理使用 new
关键字直接创建的对象。这就是您在 getInstance()
方法中所做的。此外,您不应依赖构造函数中的注入值,因为它们仅在创建对象后才被注入。
要打开注入,UserManager
的实例必须由框架创建。控制器由框架自动创建,因此注入在那里工作。
要修复您的代码,您可以从 UserManager
中创建一个服务,从构造函数中删除对 reloadUsersFromDb 的调用并将此方法标记为 运行使用 @Start
启动,如 Ninja framework documentation
中所述
我正在使用忍者框架,utilizes JPA to access a database。
我已经成功地建立了连接并在示例控制器 运行 中获得了它 class。
我想建模一个 "userManager",它在初始化时将所有当前用户从数据库加载到一个 java 映射中。
这样做时,我在调用 entitiyManagerProvider.get() 时遇到 java.lang.NullPointerException,因为 entitiyManagerProvider 设置为 null。
我不确定是什么导致了这个问题以及如何解决它,因为 "UserManager" 与我的(无问题的)测试控制器具有相同的注释。由于我对忍者或 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.");
}
}
问题在于注入永远无法处理使用 new
关键字直接创建的对象。这就是您在 getInstance()
方法中所做的。此外,您不应依赖构造函数中的注入值,因为它们仅在创建对象后才被注入。
要打开注入,UserManager
的实例必须由框架创建。控制器由框架自动创建,因此注入在那里工作。
要修复您的代码,您可以从 UserManager
中创建一个服务,从构造函数中删除对 reloadUsersFromDb 的调用并将此方法标记为 运行使用 @Start
启动,如 Ninja framework documentation