I wanted to persist an object(ReportBean) to the database, but I got error message:
javax.persistence.TransactionRequiredException: Transactio
Where have I made a mistake?
You seem to think that @TransactionManagement(TransactionManagementType.CONTAINER) enables container managed transactions and that @TransactionAttribute(TransactionAttributeType.REQUIRED) then enables a transaction on a method, for a non EJB bean.
This is however not (yet) possible in Java EE.
The @TransactionManagement annotation is only used to switch an EJB bean that already gets CMT from the container into BMT (Bean Managed Transactions). The CONTAINER constant is more for completeness, it's what you get when you omit the annotation altogether.
Likewise, the @TransactionAttribute will not enable transactions for a method on a non-EJB bean. The annotation itself exists to switch the transaction into another type (like REQUIRES_NEW). For an EJB it would not even be normally needed, since this too is the default and it too mainly exists for completeness, but can also be used to switch a single method back to REQUIRES if transactions are changed on the class level.
What is the right way to implement CMT?
The right way is to use a component model that already gets CMT from the container, like a stateless session bean:
@Stateless
public class ValidateReportAction extends ReportAction {
@PersistenceContext(unitName = "MyPersistenceUnit")
private EntityManager em;
public String createReport() {
ReportBean report = new Report();
// set report properties
em.persist(report)
}
}
Then inject this bean (using @EJB or @Inject) into your named beans and use it. Alternatively this bean can be named too using @Named so it can be used directly in EL, but this is not always recommended.
The @Stateless bean does not allow scoping (it's basically 'invocation-scoped'), but the @Stateful model can be session scoped as your original bean was. However, with the given functionality it doesn't need to be session scoped. If you only did this for the entity manager, then remember:
There are ways to implement something that looks a bit like CMT using CDI and JTA, but if you want true CMT then for the moment this is the only way. There are plans to break the fixed component models like stateless, stateful, singleton and message driven up into individual (CDI) annotations (see http://java.net/jira/browse/EJB_SPEC, and specifically for your question Decoupling the @TransactionAttribute annotation from the EJB component model), but this hasn't happened yet.