Reputation: 121
Shall a bean which is for instance used as cdi application scoped contain jpa read/write stuff or should I use always EJB for db stuff? I read somewhere on the internet that cdi shall not contain db stuff. Is that true?
Upvotes: 3
Views: 4355
Reputation: 1377
YES, you can manage db stuffs on CDI beans using @Transactional
InterceptorBinding if you are on any JavaEE 7 plus editions or JakartaEE
Take a look at the Javadoc : @Transactional
Here are the steps to inject EntityManager
with CDI
without EJB
First create a producer to produce the EntityManager
.
public class EntityManagerProducer {
@PersistenceContext(name = "customer-orders-unit")
private EntityManager em;
@Produces
@RequestScoped
public EntityManager getEntityManager() {
return em;
}
}
Create your bean to do DAO actions.
public MyCDIBeanDao{
@Inject
private EntityManager m_entityManager;
@Transactional
public doStuff(){
// Here you are in a Container managed Transaction
m_entityManager.persist(...)
}
}
Don't forget to add beans.xml
in your WEB-INF
folder.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
bean-discovery-mode="all"
version="2.0">
</beans>
Upvotes: 8
Reputation: 1851
As always the answer is it depends... It depends on your specific use case.
In Java EE we use @EJB
beans as the place where we Inject the EntityManager
to later perform read/write on JPA Entities.
Why we do this? Because we need Transactions
. By default when you annotate a bean with @Stateless
all the methods in it are Transactional
and you get it all for free. Transactions enable you to update multiple tables in an atomic fashion, they will either succeed all or fail.
Example:
In your method updateABC()
you want to update Table A,B,C and you want all of them to succeed or the transaction to be Roll-backed:
@Stateless
public class MyClass{
@PersistenceContext
EntityManager em;
public void updateABC(){
A a= em.find(A.class, aId);
//here update some fields on the entity "a"
B b= em.find(B.class, bId);
//here update some fields on the entity "b"
C c= em.find(C.class, cId);
//here update some fields on the entity "c"
}
}
And this is it... you're done. All your updates will be magically persisted to the DB or nothing.
Do you need something like this? Go for EJB's. You need not? You want to do the job manually? then create your own beans...
Upvotes: 4