简体   繁体   中英

CDI Injection and JPA EntityManager

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM