为什么在尝试开始事务时会出现NullPointerException?

时间:2014-06-29 21:12:47

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

在此行中获取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 
}

1 个答案:

答案 0 :(得分:3)

如我的评论中所述,问题在于您手动创建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");