data-source with JBoss EAP in my project.
For some reason when i try to persist an object i get the error below.
JBAS011469: Transaction is required to perform this operation (either
use a transaction or extended persistence context):
javax.faces.FacesException: #{back.salvar}:
javax.persistence.TransactionRequiredException: JBAS011469:
Transaction is required to perform this operation (either use a
transaction or extended persistence context)
There is #Transactional method but this method launch the error.
Anyone?
#Stateless
#Named
public class BaseDao implements Serializable
{
private static final long serialVersionUID = -8993128837557701804L;
#PersistenceContext
protected EntityManager manager;
#Transactional
public void persist(Object object)
{
manager.persist(object);
}
}
PS: All objects are injected with CDI, the manager is injected with the object class org.jboss.as.jpa.container.TransactionScopedEntityManager
As your CDI bean is an EJB stateless session bean, you don't have to use #Transactional annotation here since EJB have Container Managed Transaction (CMT) by default.
#Transactional is useful to manage transaction transaction on a CDI managed bean (i.e. POJO).
Related
Having for eg:
#Stateless
public class EntityRepositry{
#Inject
EntityManager em;
public void create(Entity e){
// op1 success
// op2 failed
}
}
As Stateless EJB are by default transactional, I would understand how the transaction if a system exception (like OptimisticLockedException) is thrown, will be rollbacked? How em.getTransaction().rollback will be called implicitly?
Thanks in advance.
EntityManager are injected with #PeristenceContext annotation (or may you have a CDI producer?)
If the persistence unit is declared to use JTA transactions
<persistence-unit name="myname" transaction-type="JTA">
then the EJB transaction is bound to the JPA transaction and viceversa.
JPA Exceptions rollback the whole transation but remember that any RuntimeException will rollback a transaction, checked exception doesn't.
So if you use JTA transaction management you don't have to rollback manually transactions, just throw or catch the right exception (catching RuntimeException don't prevent the transaction to be rolled back but allow you to manage it).
On Finchley.SR2, here is the code
#Configuration
#EnableAutoConfiguration
#SpringBootApplication
#EnableBinding(Processor.class)
#RestController
public class Application {
private static Logger log = LoggerFactory.getLogger(Application.class);
#Autowired
private Processor processor;
#Autowired
MappingJackson2MessageConverter testConverter;
#Bean
#StreamMessageConverter
MappingJackson2MessageConverter createTestConverter(){
return new MappingJackson2MessageConverter();
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
When I start up, I got
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.cloud.stream.messaging.Processor' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
But if I take out #StreamMessageConverter, the Processor can be autowired successfully.
What should I do to keep my customized message converter and autowired Processor at the same time? Thanks!
There is a lot going on there, so lets try to parse it put. . .
First question, why do you need to autowire the following?
#Autowired
private Processor processor;
You, generally don't need to interact with Processor directly since it is used bt the framework to provide a delegation/connectivity model between remote destinations exposed by the binders and your message handlers
Further more, your actual issue is related to a lifecycle which may be a minor yet harmless bug on our end and probably relates to configuring and autowiring Processor in the same configuration class.
Second:
#Configuration
#EnableAutoConfiguration
#SpringBootApplication
You only need one
#SpringBootApplication
Third:
Why do you need to configure MappingJackson2MessageConverter? Content type conversion is a transparent feature of he framework and while we do provide an ability to configure custom message converters, the one you are configuring is already configured by the framework and in fact is the first in the stack of seven pre-configured message converters
The final question:
What is it that your are trying to do? Can you explain your use case?
I've got that JAX-RS webservice:
#Path("/my")
public class MyWS {
#Inject
private MyService myService;
#POST
#Path("/save")
#Consumes("application/json")
public void save(SaveParam saveParam) {
myService.save(saveParam);
}
}
and that #Stateless service:
#Stateless
public class MyService {
#PersistenceContext
protected EntityManager entityManager;
#TransactionAttribute
public void save(SaveParam saveParam) {
entityManager.persist(saveParam);
}
}
Using JBoss EAP 6.2, myService is always null (not injected) when arriving in the save method.
I've tried to add #ApplicationScoped to MyWS class, but the same behavior is happening (NullPointerException). The only solution is to declare MyWS also as #Stateless, but that's not really have any sens, have it?
Is this a bug in JBoss EAP?
All my classes are in the same war project and I have a WEB-INF/beans.xml using CDI 1.0 spec. I also have a class extending javax.ws.rs.core.Application and declaring the #ApplicationPath.
I guess it is a bug if you configure your REST service in web.xml.
I have the same issue and i was getting crazy about this.
Just clean up the web.xml and it should not have anything related to REST.
#ApplicationPath is good enough for all REST setup.
Environment
Application server: JBoss AS7 (7.1.1 Final)
JPA implementation: EclipseLink (2.4.1)
OS: Windows 7 DB: PostgreSQL 8.4
Update 2, solved
The problem was that i instantiated the AccountService class instead of injecting it using #EJB. After fixing that EntityManager was inected correctly in the service and a transaction was available when doing em.persist(account);
Update
I made a minimal project that shows my problems. Posted to Github:
https://github.com/gotling/jboss-eclipselink-problem
I have two problems that are probably related and due to me not understanding the use of EJB's correct.
I can not get EnityManager to be injected in AccountService.java in persistance JAR, resulting in NullPointerException.
If sending EntityManager in constructor to AccountService no tranasaction is found when doing em.persist.
Project structure
EJB
lib/persistanceunit.jar
web-service.war
Problem
I'm trying to get JBoss to manage transactions in my Java EE service. Problem is that EclipseLink does not seem to pick up the transaction managed by JBoss when trying to persist an entity.
I have followed the guide https://community.jboss.org/wiki/HowToUseEclipseLinkWithAS7 (Alternative 1 and Alternative 2 Step 4) on how to configure JBoss with EclipseLink.
Setup
WAR
Entity manager is injected like this in web-service.war:
#WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
#PersistenceContext(unitName="foo")
EntityManager em;
public void notify(Notify notify) {
AccountService accountService = new AccountService(em);
accountService.create(notify);
}
}
There is actually a controller class between the class above and the service class, where transformation of the Account object is done, removed it to shorten code.
Persistance Unit
Entity is created like this
AccountService.java in persistanceunit.jar
#Stateless
public class AccountService {
private EntityManager em;
public AccountService(EntityManager em) {
this.em = em;
}
public void create(Account account) {
em.persist(account);
}
}
Stack trace
When calling a WS that should persist the Account entity I get an exception on em.persist(account);
...
Caused by: javax.persistence.TransactionRequiredException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context)
at org.jboss.as.jpa.container.AbstractEntityManager.transactionIsRequired(AbstractEntityManager.java:692) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.as.jpa.container.AbstractEntityManager.persist(AbstractEntityManager.java:562) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]
at se.magos.service.AccountService.create(AccountService.java:50) [persistenceunit-0.0.1-SNAPSHOT.jar:]
Questions
I've enabled Trace logging. Should not id.au.ringerc.as7.eclipselinkpersistence be visible in the log?
Is it somehow possible to get the EntityManager injected inside the service class inside the persistanceunit.jar?
In which JBoss / EclipseLink version should this wor out of the box?
You should annotate the bean with #TransactionManagement(TransactionManagementType.CONTAINER) and the create method with #TransactionAttribute(TransactionAttributeType.REQUIRED).
The first annotation is required in order to let the application server know that transactions are managed by the container, the latter to let the method start a transaction, if there is no current one, as soon as it is invoked.
The problem was that AccountService class was instantiated instead of injected using #EJB annotation. After fixing that EntityManager was injected correctly in the service and a transaction was available when doing em.persist(account);
Before
#WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
#PersistenceContext(unitName="foo")
EntityManager em;
public void notify(Notify notify) {
AccountService accountService = new AccountService(em);
accountService.create(notify);
}
}
After
#WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
#PersistenceContext(unitName="foo")
EntityManager em;
#EJB
AccountService accountService;
public void notify(Notify notify) {
accountService.create(notify);
}
}
I have an EAR application with an EJB module, that contains one persistence unit and many EJBs (as service and DAO layer).
#Stateless
public class BranchDAO {
#PersistenceContext
private EntityManager entityManager;
}
But DAOs as Stateless beans are not recommended. So I create this annotation using CDI:
#Dependent
#Stereotype
#Target(ElementType.TYPE)
#Retention(RetentionPolicy.RUNTIME)
public #interface DAO {
}
After my DAO is changed to not use #Stateless:
#DAO
public class BranchDAO {
#PersistenceContext
private EntityManager entityManager;
}
But the Glassfish doesn't bring up the entity manager when the application starts. And when I call the DAO, the entity manager is in an illegal state.
java.lang.IllegalStateException: Unable to retrieve EntityManagerFactory for unitName null
This error only occurs in Glassfish 3, but not in JBoss AS 6. Using JBoss AS 6 I can see the Hibernate logs in startup (but I don't see them with Glassfish).
As a temporary solution I created an Stateless bean with the content below. It's not beautiful solution, but works fine in Glassfish.
#Stateless
#Startup
public class AutoStartEntityManager {
#PersistenceContext
private EntityManager entityManager;
}
So, how I can force Glassfish to bring up EntityManager when I'm not using #Stateless in my DAO?
Try specifying explicitly the unitName:
#PersistenceContext(unitName="yourJPAUnitName")
private EntityManager manager;
(A sidenote - are you sure you need the DAO in dependent scope? Shouldn't it be singleton?)