【问题标题】:JSF simple entity persistence from a form来自表单的 JSF 简单实体持久性
【发布时间】:2012-11-06 01:22:23
【问题描述】:

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

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>

我的错误在哪里?

【问题讨论】:

    标签: jsf nullpointerexception dao facade


    【解决方案1】:

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

    使UserDAO(和UserFacade)成为@Stateless EJB

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

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

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

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

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 2012-09-25
        • 2013-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-13
        • 2012-05-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多