2

我认为这个问题很简单,我得到了错误:

Caused by: java.lang.NullPointerException
at co.edu.unal.bienestar.dao.UserDao.save(UserDao.java:27)
at co.edu.unal.bienestar.facade.UserFacade.createUser(UserFacade.java:18)
at co.edu.unal.bienestar.mb.UserMB.createUser(UserMB.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.el.parser.AstValue.invoke(AstValue.java:262)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
... 27 more

当我尝试使用只有实体类的应用程序创建新用户时:

@Entity
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String username;
    private String password;
    private Role role;

    <here getters and setters>
}

数据访问对象:

public class UserDao {

    @PersistenceContext
    private EntityManager em;


    public void save(User user) {
        em.persist(user);
    }

    public void delete(User user) {
        User userToBeRemoved = em.merge(user);
        em.remove(userToBeRemoved);
    }

    public User update(User user) {
        return em.merge(user);
    }

    public List<User> findAll() {
        TypedQuery<User> query = em.createQuery(
                "SELECT u FROM User u ORDER BY u.id", User.class);
        return query.getResultList();
    }
}

门面:

public class UserFacade {

    private UserDao userDao = new UserDao();

    public void createUser(User user) {
        userDao.save(user);
    }

    public List<User> listAll() {
        List<User> result = userDao.findAll();
        return result;
    }
}

用户管理的 Bean:

@SessionScoped
@ManagedBean(name = "userMB")
public class UserMB implements Serializable {
    public static final String INJECTION_NAME = "#{userMB}";
    private static final long serialVersionUID = 1L;
    private User user;
    private UserFacade userfacade;


    public User getUser() {
        if (user == null) {
            user = new User();
        }
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public void createUser() {
        getUserfacade().createUser(user);
    }

    public UserFacade getUserfacade() {
        if (userfacade == null){
            userfacade = new UserFacade();
        }
        return userfacade;
    }
}

最后从 JSF 页面我调用这样的方法:

    <f:view>
        <h:form>
            <h1><h:outputText value="Create/Edit"/></h1>
            <h:panelGrid columns="2">
                <h:outputLabel value="Username:"/>
                <h:inputText id="username" value="#{userMB.user.username}" title="username" />
                <h:outputLabel value="Password:" />
                <h:inputText id="password" value="#{userMB.user.password}" title="password" />
                   <h:outputLabel value="ID:" />
                   <h:inputText id="id" value="#{userMB.user.id}" title="id" />                                      
            </h:panelGrid>
            <h:commandButton action="#{userMB.createUser}" value="create"/>
        </h:form>
    </f:view>

我的错误在哪里?

4

2 回答 2

2

@PersistenceContext仅适用于托管类。您的UserDAO(and UserFacade) 似乎完全不受管理并手动创建。这样EntityManager就不会被注入了。您还需要手动创建它。现在是null这样,这就解释了NullPointerException

使UserDAO(和UserFacade)成为@StatelessEJB

@Stateless
public class UserDAO {
    // ...
}

并用于@EJB注入它们(并删除 getter 中的延迟加载)

@EJB
private UserFacade userFacade; // Also on userDAO.

或者,如果您的环境不支持 EJB(例如 Tomcat),那么您需要将其升级到 TomEE 或在其上安装 OpenEJB,或者寻找替代框架来管理您的服务外观和 DAO。Spring 经常被使用,但是如果 Java EE 6 已经提供了 EJB3 的强大功能,你为什么要选择它呢?

于 2012-11-06T01:29:44.950 回答
1

BalusC 写道:“@PersistenceContext 仅适用于托管类。”

那么,是否可以通过@PersistenceContext 注解在UserMB 中创建EntityManager,并将其传递给DAO?

(我知道这不是 EE6 背后的想法,但如果替代方案如此复杂,人们可能会考虑这一点。然后你可以继续使用 tomcat,并拥有一个生命周期管理的 EntityManager,如果我做对了。)

(很抱歉将其作为答案而不是评论发送,但我必须减少分数。)

于 2014-05-29T18:34:05.357 回答