Java 为什么在尝试开始事务时会出现NullPointerException?
在我得到这行中的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(); 我不明白为什么。我试图把它从试抓块中拿出来,但得到了同样的结果。在最后一个示例中,我还
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也很好,因为我能够获取我的用户并将他们存储在数据库中。