【问题标题】:Why do I get a NullPointerException while trying to begin transaction?为什么我在尝试开始交易时收到 NullPointerException?
【发布时间】:2014-06-29 21:12:47
【问题描述】:

在我在这一行中得到 NullPointerException 之前

EntityManager manager = emf.createEntityManager();

但我通过在上面添加一行来修复它

emf =  Persistence.createEntityManagerFactory("main");

现在我在这一行得到 NullPointerException

transaction.begin();

我不明白为什么。我试图从 try catch 块中取出它,但得到了相同的结果。同样在最后我尝试添加 emf.close();但错误没有得到修复。另外,我包含 @Named 注释是因为有人建议我这样做。

import java.io.Serializable;
import javax.inject.Named; 
import javax.inject.Inject; 
import java.sql.*;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceUnit;
import javax.persistence.TypedQuery ; 
import javax.transaction.UserTransaction;
import javax.transaction.RollbackException; 
import javax.persistence.criteria.*;
import java.util.List;
import java.util.*;

@Named
public class UserManager implements Serializable{

   @PersistenceUnit(unitName="main")
   private EntityManagerFactory emf;

   @Resource
   private UserTransaction transaction;

   public UserManager() {}

   public UserTransaction getTransaction() { return transaction; }
   public void setTransaction(UserTransaction transaction) { this.transaction = transaction; }

   public void addUser(User v) throws Exception {
    emf =  Persistence.createEntityManagerFactory("main");
        EntityManager manager = emf.createEntityManager();
        boolean commit;
        try {   
    transaction.begin();
        manager.joinTransaction();
    commit = false;
        try {
        manager.persist(v);
        transaction.commit();
        commit = true;
        }finally {
                if(commit==false){
            transaction.rollback();
                }
         }
        }finally {     
         manager.close();
             //emf.close();
    }
   }



@Named("subBean")
@RequestScoped
public class UserBean implements Serializable{

   private List<User> users;
   private UserManager vm;
   private User v;
   private int total;

   public UserBean() {
      this.total= 0;
      users = new ArrayList<User>();
      vm = new UserManager();
      v = new User();
   }

   public String addUserAction() throws Exception {
      vm.addUser(v);
      users = getUsers();
      return "submit1";

   }

   //getters and setters 
}

【问题讨论】:

  • 您声明了事务,但它没有被初始化。你是在调用 addUser() 之前调用 setTransaction() 吗?
  • @shaunc 它应该由 CDI 注入。
  • 看起来您正在手动初始化 UserManager 类,因此 CDI 无法注入相应的变量。如果您是手动完成工作,那么您不应该使用 CDI,或者应该检查您是否遵循正确的设计。
  • 我从另一个是 CDI bean 的类中调用 addUser(),并且在 RequestScoped 处命名,并且在该类中,我有一个 AddUserAction 方法,该方法在 UserManager 类中调用 addUser。我确实在 addUser 方法之上有 get 和 setTransaction 方法,但我没有在任何地方调用它们。他们在那里,因为我使用 @Resource 私有 UserTransaction 事务;
  • @user1282256 提供必要的代码,看看你是如何做到这一点的。

标签: java jpa nullpointerexception cdi named-entity-recognition


【解决方案1】:

正如我在评论中指出的,问题在于您手动创建了UserManager bean 的实例,而 CDI 无法注入变量。此处注明:

@Named("subBean")
@RequestScoped
public class UserBean implements Serializable{
   //variable is just declared...
   private UserManager vm;

   public UserBean() {
      //and here you're initializing it manually...
      vm = new UserManager();
   }

   //rest of your code...
}

让 CDI 通过注入变量来完成它的工作:

@Named("subBean")
@RequestScoped
public class UserBean implements Serializable{
   //variable is just declared
   //and notify CDI it should inject an instance when creating an instance of the client class
   @Inject
   private UserManager vm;

   public UserBean() {
      //no need to initialize it ever
      //vm = new UserManager();
   }

   //rest of your code...
}

通过这样做,您也不需要创建任何应该注入到其他 bean 中的字段,这意味着您不需要手动初始化 emf 字段:

//this line should be commented as well...
//emf =  Persistence.createEntityManagerFactory("main");

【讨论】:

  • 谢谢它解决了我的问题。我没有关闭 EntityManagerFactory 也很好,因为我能够获取我的用户并将它们存储在数据库中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-14
  • 1970-01-01
  • 1970-01-01
  • 2013-05-25
  • 1970-01-01
  • 2021-11-02
相关资源
最近更新 更多