Pregunta

I think that the question is simple, I get the error:

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

When I try the create a new user, with a application which only have a entity class:

@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>
}

a Data Access Object:

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();
    }
}

a facade:

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;
    }
}

User Managed 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;
    }
}

And finally from JSF page I call the method like this:

    <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>

Where is my mistake?

¿Fue útil?

Solución

@PersistenceContext works only in managed classes. Your UserDAO (and UserFacade) seems to be completely unmanaged and created manually. This way the EntityManager won't be injected at all. You'd need to manually create it as well. Right now it is null, which thus explains the NullPointerException.

Make the UserDAO (and UserFacade) a @Stateless EJB

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

and use @EJB to inject them (and remove lazy loading in getter)

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

Or, if your environment doesn't support EJBs (e.g. Tomcat), then you'd need to either upgrade it to TomEE or to install OpenEJB on top of it, or to look for an alternate framework to manage your service facades and DAOs. Spring is often used, but why would you choose for it if Java EE 6 already offers the EJB3 awesomeness?

Otros consejos

BalusC wrote: "@PersistenceContext works only in managed classes."

So, can it be an option to create the EntityManager in the UserMB by @PersistenceContext annotation, and pass it on to the DAO?

(I am aware that this is not the idea behind EE6, but if the alternatives are so complicated, one might think about this. Then you can stay with tomcat, and have a life cycle managed EntityManager, if I got this right.)

(Sorry for sending this as an answer instead of a comment, but i have to less points.)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top