EJB 3.0 Access two databases from single session bean EJB 3.0 - ejb-3.0

I want to access two databases from a single stateless session bean in EJB 3.0. I have created a session bean in which I have declared two entity managers, in order to communicate with the two database. The entity managers are defined in this way in my stateless session bean:
#PersistenceContext (unitName="abc") private EntityManager manager;
#PersistenceContext (unitName="xyz") private EntityManager manager1;
Using the first entity manager I am getting data from one database, which I then insert into the second database, using the second entity manager. My problem now is that I am able declare both entity managers but I am not able to use them both at the same time. I have to comment out using one of them or else I get this exception:
Caused by: org.hibernate.exception.GenericJDBCException: Cannot open connection
Caused by: org.jboss.util.NestedSQLException: Could not enlist in transaction on
entering meta-aware object!;
- nested throwable:" "Caused by:
org.jboss.resource.JBossResourceException: Could not enlist in transaction on entering meta-aware object"
"Caused by: javax.transaction.SystemException: java.lang.Throwable:"

Each method in a stateless session bean gets a transaction. If you're accessing more than one database within the method you must have xa datasources, not tx.
I've run into this before and there is a work-around. Create separate stateless session beans for each database, then turn off transactions for your original method in the original stateless session bean:
#EJB(mappedName="com.abc.AbcManager")
private AbcManager abcManager;
#EJB(mappedName="com.xyz.XyzManager")
private XyzManager xyzManager;
#TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public MyResponse getMyData(MyRequest request) throws MyException {
Collection<Data> data = abcManager.getData();
xyzManager.storeData(data);
return null;
}
The methods on the new session beans will create their own transactions but you can still have a single stateless session bean coordinating the other two.

Related

Reusing the JDBC connection from Hibernate with Spring

I've searched for a long time on this topic however I cannot find a solution to my specific issue. I am trying to figure out how I can pull the JDBC connection from Hibernate so that I can run a query for generating reports. I am trying to use a JDBC connection since my reports don't map well to the existing Entity situation that we have.
Right now, my application has a bean for a LocalContainerEntityManagerFactoryBean and a bean for DataSource, which is a just a DriverManagerDataSource, both residing in a core configuration file. The problem that I am having is, whenever I try to wire up my DAO to access the JDBC connection by doing something like this:
#PersistenceContext
private EntityManagerFactory entityManagerFactory;
private SessionFactory session;
public SystemUsageReportDAO() {
session = entityManagerFactory.unwrap(SessionFactory.class);
}
I simply get a null pointer exception at the constructor line. I've tried all manner of getting the connection from the EntityManagerFactory, however I'm not sure how I can do it. Any advice would be appreciated.
I know that my end goal is to get a Session object, and from there I can call doWork, however getting to that Session is proving quite the task for me.

Tomcat JSF Session BEan #Predestroy "Session already invalidated"

So I try to access an attribute of my HttpSession on my #PreDestroy method on a #SessionScoped JSF managed bean using
session.getAttribute("myAttribute");
But I get a
java.lang.IllegalStateException: getAttribute: Session has already been invalidated
Why?
I need to access the list of connections to external services opened by that session before one of my session beans is destroyed, and they are of course stored on a session attribute object.
How can I do that?
Explicitly accessing a session attribute in a session scoped managed bean doesn't make sense. Just make that attribute a property of the session scoped managed bean itself.
#SessionScoped
public class YourSessionScopedBean implements Serializable {
private Object yourAttribute; // It becomes a session attribute already.
#PreDestroy
public void destroy() {
// Just access yourAttribute directly, no need to do it the hard way.
}
}
The exception you faced occurred because the session was explicitly invalidated via a HttpSession#invalidate() call instead of "just" expired.

EJB 3.0 , are thread safe?

Hy,
I am a newbie in EJB. Now I am studying the EJB 3.0 specification. If I have two different JSF managed beans like the next ones:
#ManagedBean
public class CocheBean {
#EJB
private ICochesService cochesService = null;
}
#ManagedBean
public class UsuarioBean {
#EJB
private ICochesService cochesService = null;
}
The injecteds implementations for cochesService are the same in both cases?, I mean, for each annotation, the ejb container gets back a new object or is the same object?
Why do they refer to EJBs as session beans? Are they session scoped? Do they exist till the session of a user expires?
Its said that you dont have to worry if the stateless EJB are thread safe because the container has a pool of different instances for each request but if they are stateless and there is no danger that multiple threads access to just one ejb, why the container creates a pool of them and not just one?
Using JSF managed beans, if this bean is request or session scoped and because we inject the ejbs in this beans, they cannot be called more than once per user or per request at the same time, right?
How to specify the transactional atributes to EJB bean methods, with JPA annotations?
Thanks
This depends - if ICochesService is stateless than each of them will have different object. If it's stateful or singleton than both beans will have the same object injected
Answer to both questions is no :) See the Oracle docs
Exactly
You can call as many beans as you want per each request.
See the Oracle tutorial for Java Transaction API.

Managed bean and datasource connections in ejb3.1

I have a bean (dbbean) that has datasource which is injected at runtime. this managed bean is used by many dao beans. I use ejb3.1 in jboss environment. I get frequent error saying closing the connection for you, please close them yourself. this dbbean is not singleton. should i need to manage the bean with scope? I have finally block that will close all database resources.
Note: I have postconstruct annotated method that will create a connection and predestroy annotated method which will close the opened connection.
thanks

Thread safety hibernate DAO layer

I have a list of Transaction objects.
List<Transaction> transactions;
I need to batch process these transactions by creating a pool of threads which update transactions concurrently.
These threads update these transactions using the same DAO class(Spring singleton bean) to update the transaction. I'm using Hibernate as ORM
What am I to consider to make sure my code is thread safe? I'm a bit confused.
Here's the DAO class. SessionFactory is also defined as a Spring bean which is then autowired to DAO class.
#Autowired
SessionFactory sessionFactory;
#Override
public Transaction update(Transaction transaction) {
Session session = sessionFactory.openSession();
session.beginTransaction();
session.update(transaction);
session.getTransaction().commit();
return transaction;
}
To get much better performance look at pooling the DB connections, there are open source implementations like c3p0 which works nicely with spring and hibernate. This is particularly import for batch processing.
Are you using the hibernate implementation of SessionFactory? If that is the case then it is indeed thread safe so you should be good.
Another suggestion is to look at spring batch which might be useful for your situation.
Update: you've already said you are using Hibernate so the SessionFactory should be good.
I think your problem is a bit bigger than threadsafety, you need to evoke transaction management.
The session generated by the session factory is threadlocal (spring's HibernateTransactionManager and the beanFactory that creates the sessuinFactory -for ex: AnnotationSessionFactoryBean- manages all this stuff)
So Your code is Safe ;)

Resources