EntityManagerProvider вводится как ноль
Я использую инфраструктуру ниндзя, которая использует JPA для доступа к базе данных.
Мне удалось установить соединение и запустить его в примере класса контроллера.
Я хотел бы смоделировать "userManager", который после инициализации загружает всех текущих пользователей из базы данных в карту Java.
При этом я сталкиваюсь с java.lang.NullPointerException при вызове liciyManagerProvider.get(), так как priviyManagerProvider имеет значение 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.");
}
}
1 ответ
Проблема в том, что внедрение никогда не работает с объектами, созданными напрямую new
ключевое слово. И это то, что вы делаете в getInstance()
метод. Также не следует зависеть от введенных значений в конструкторе, так как они вводятся только после создания объекта.
Чтобы включить инъекцию, экземпляр UserManager
должен быть создан рамкой. Контроллеры автоматически создаются фреймворком, поэтому там работает инъекция.
Чтобы исправить свой код, вы можете создать сервис из UserManager
удалите вызов reloadUsersFromDb из конструктора и отметьте этот метод для запуска при запуске с @Start
как описано здесь в документации Ninja Framework