Question

It has been some hours I'm working on this but still I haven't figured out what is the right way of using JPA with JSF.

I have a session scoped managed bean that can do a lot of things, and one of them is persisting some entity objects. At the beginning, I created a producer method, request scoped, that build my EntityManager objects. Anyway a read here that injecting a requested scoped bean into a session scoped ones is done wrapping that instance into an Instance object. Done. But when I try to use that EM I got a transaction required exception. Keep on reading on the internet someone tells that I have to inject the EM directly into my managed beans using the PersistenceContext annotation. Anyway I thought it has more sense using a persistenceUnit annotation and creating my em inside my methods where I needed them. Injection works, but I still get a transaction required exception when I try to persist something!

So here I am asking: what is the right way of doing this?

edit: I'm using Jboss eap 6.2 using default settings. I'm deploying my data source using a xml file inside WEB-INF, so I'm using JTA.

Was it helpful?

Solution

I'm an idiot. I've already clashed with this problem in the past but I forgot.

To everyone that steps here with the same problem here is the solution. Container Managed Transactions only works if the container is an EJB. It does NOT works if the container is JSF! It doesn't matters how you inject your entity managers, injections succeed but the created object will not works.

The way of solving it, is creating an EJB DAO object that deal with the database for you. Something like

@Named
@Stateless
public class MyDAO {

@PersistenceContext(unitName = "SRA")
private EntityManager em;

public void save(Object o) {
    em.persist(o);
    em.flush();
}

}

and then injecting those object inside your managed bean like this:

@ManagedBean
@SessionScoped
public class MyManagedBean {
@EJB
private MyDAO dao;

public void action() {
....
    dao.save(o);
}

}

injecting directly an EntityManager into a Managed Bean will give you a Transaction Required Exception.

I'm still unsure about injecting something like that into a broader scoped bean. I will look into this later.

OTHER TIPS

"someone tells that I have to inject the EM directly into my managed beans using the PersistenceContext annotation."

If you look at the Java EE tutorial, that's exactly what they do

@Singleton
public class MyUserDatabaseEntityManager { 
    // declare a producer field 
    @Produces
    @UserDatabase
    @PersistenceContext
    private EntityManager em;
}

@ConversationScoped
@Stateful
public class RequestBean {

    @Inject
    @UserDatabase
    EntityManager em;

This may not completely answer your question, but hope it helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top