1
votes

I am seeing two classes:

/** * This class uses CDI to alias Java EE resources, such as the persistence context, to CDI beans * */

public class Resources {
    @Produces
    @PersistenceContext
    private EntityManager em;

    @Produces
    public Logger produceLog(InjectionPoint injectionPoint) {
        return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
    }

    @Produces
    @RequestScoped
    public FacesContext produceFacesContext() {
        return FacesContext.getCurrentInstance();
    }
}

and

// The @Stateless annotation eliminates the need for manual transaction demarcation
@Stateless
public class MemberRegistration {

    @Inject
    private Logger log;

    @Inject
    private EntityManager em;

    @Inject
    private Event<Member> memberEventSrc;

    public void register(Member member) throws Exception {
        log.info("Registering " + member.getName());
        em.persist(member);
        memberEventSrc.fire(member);
    }
}

I have 2 questions on this:

1) MemberRegistration can inject "log" and "em" directly, is that because the Resources already define them by using @Produces annotation? Without the Resources class, would the MemberRegistration class still work? I am trying to understand whether or how the two classes are related, and how the CDI works.

2) In MemberRegistration's register method, there is only a "em.persist()" method used. A complete flow of using EntityManager looks like the following. In the example application, I didn't see methods "commit()" and "close()" are used. So how the transaction is committed and closed?

    EntityManager entityManager = entityManagerFactory.createEntityManager();
        entityManager.getTransaction().begin();
        entityManager.persist( SomeObject );
        entityManager.getTransaction().commit();
        entityManager.close();
1
1. What does your test say? 2. The whole point of EJBs is that they handle transactions for you. You even have a comment on your code explaining it.JB Nizet
Without @Stateless, it wouldn't work, right? Learning this new stuff.user697911

1 Answers

1
votes

Answering your questions:

1) MemberRegistration can inject "log" and "em" directly, is that because the Resources already define them by using @Produces annotation?

Yes. @Inject will work only for types that are known to CDI (are discovered via class-path scanning or declared manually via @Produces). So without your Resources class, which defines EntityManager and Logger as a CDI managed beans, injection via @Inject would not work.

BTW. For details you can read cdi-spec-1.2 - PDF version is 170 pages long, not that big, but also not so short.

2) So how the transaction is committed and closed?

... you even have a valid comment in your code: the @Stateless annotation eliminates the need for manual transaction demarcation. For details read something about CMT transactions in EJB.

Honestly, I agree with @JBNizet. It is disappointing to see you asking such questions (especially the first one) which can be answered immediately by yourself with just a quick test.