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

Java 为什么在尝试开始事务时会出现NullPointerException?,java,jpa,nullpointerexception,cdi,named-entity-recognition,Java,Jpa,Nullpointerexception,Cdi,Named Entity Recognition,在我得到这行中的NullPointerException之前 EntityManager manager = emf.createEntityManager(); 但我通过在上面加一行来修正它 emf = Persistence.createEntityManagerFactory("main"); 现在我在这行中得到了NullPointerException transaction.begin(); 我不明白为什么。我试图把它从试抓块中拿出来,但得到了同样的结果。在最后一个示例中,我还

在我得到这行中的NullPointerException之前

EntityManager manager = emf.createEntityManager();
但我通过在上面加一行来修正它

emf =  Persistence.createEntityManagerFactory("main");
现在我在这行中得到了NullPointerException

transaction.begin();
我不明白为什么。我试图把它从试抓块中拿出来,但得到了同样的结果。在最后一个示例中,我还尝试添加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 
}
import java.io.Serializable;
导入javax.inject.Named;
导入javax.inject.inject;
导入java.sql.*;
导入javax.annotation.Resource;
导入javax.persistence.EntityManager;
导入javax.persistence.EntityManagerFactory;
导入javax.persistence.persistence;
导入javax.persistence.PersistenceUnit;
导入javax.persistence.TypedQuery;
导入javax.transaction.UserTransaction;
导入javax.transaction.RollbackException;
导入javax.persistence.criteria.*;
导入java.util.List;
导入java.util.*;
@命名
公共类UserManager实现可序列化{
@PersistenceUnit(unitName=“main”)
私人实体管理工厂emf;
@资源
私人用户交易;
公共用户管理器(){}
public UserTransaction getTransaction(){return transaction;}
public void setTransaction(UserTransaction事务){this.transaction=transaction;}
public void addUser(用户v)引发异常{
emf=Persistence.createEntityManagerFactory(“main”);
EntityManager=emf.createEntityManager();
布尔提交;
试试{
transaction.begin();
manager.joinTransaction();
提交=错误;
试一试{
经理:坚持(五);
commit();
提交=真;
}最后{
if(commit==false){
transaction.rollback();
}
}
}最后{
manager.close();
//emf.close();
}
}
@命名(“子bean”)
@请求范围
公共类UserBean实现了可序列化{
私人名单用户;
私有用户管理器;
私人用户v;
私人整数合计;
公共用户bean(){
这个。总数=0;
users=newarraylist();
vm=新用户管理器();
v=新用户();
}
公共字符串addUserAction()引发异常{
vm.addUser(v);
users=getUsers();
返回“submit1”;
}
//接球手和接球手
}

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

您声明了事务,但未对其进行初始化。在调用addUser()之前是否调用setTransaction()?@shaunc它应该由CDI注入。看起来您正在手动初始化
UserManager
类,因此CDI无法注入相应的变量。如果您是手动操作,则不应该使用CDI,或者应该检查您是否遵循了正确的设计。我称之为addUser()另一个类是CDIBean,在RequestScope中有at命名,在该类中我有一个AddUserAction方法,在UserManager类中调用addUser。我在addUser方法上面有get和setTransaction方法,但我不会在任何地方调用它们。它们在那里,我使用@Resource private UserTransaction;@user1282256提供必要的代码以了解您是如何做到这一点的。谢谢,它解决了我的问题。我没有关闭EntityManagerFactory也很好,因为我能够获取我的用户并将他们存储在数据库中。