-
1. Re: Does Seams entityManager disturbs TransactionAttributes in EJB ?
asookazian Mar 9, 2010 7:41 PM (in response to nimo22)Generally speaking in a JSF/Seam/EJB3/JPA/Hibernate app, you should use EJB CMT (container-managed tx's), SMPC and Hibernate manual flush.
Read SiA or JPwH books for details...
-
2. Re: Does Seams entityManager disturbs TransactionAttributes in EJB ?
swd847 Mar 9, 2010 10:17 PM (in response to nimo22)This is not really ok. The EM is enlisted in the outer transaction, not the new one, so this will not do what you expect.
Use @PersistenceContext() instead to get a transaction scoped em and merge your entity (This is in the seam docs somewhere).
This may get fixed in Seam 3.
-
3. Re: Does Seams entityManager disturbs TransactionAttributes in EJB ?
nimo22 Mar 10, 2010 9:20 AM (in response to nimo22)Hello Stuart,
I do not understand that.
Actually I am using CMT with SMPC and Seams manual flushing.
The first thing which I do not understand, is this:
entityManager.getFlushMode() returns AUTO
and hibernates session.getFlushMode() returns AUTO, too.
But I have manual-flushing enabled with seams flushMode: FlushModeType.MANUAL.So where lies the difference of seams manual flushing and hibernate manual flushing?
Why does hibernate does not tell me that flush-mode is manual?The other question is:
The EM is enlisted in the outer transaction, not the new one, so this will not do what you expect.The caller is my conversation bean. The entityManager is within the EJB Session Bean.
I delete this:@TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRES_NEW)
and trigger initUpdateUsers, then it works. The manual flushing works. So there is no need to use @PersistenceContext. Am I right?
According to Seam manual (page 201):
..Therefore, if you mark a method REQUIRES-NEW then you should access the entity manager using @PersistenceContext.Would it be better to use
@PersistenceContext(type=EXTENDED) private EntityManager em;
with Hibernate manual flushing instead of SMPC and Seams manual flushing ?
-
4. Re: Does Seams entityManager disturbs TransactionAttributes in EJB ?
nimo22 Mar 10, 2010 11:06 AM (in response to nimo22)I have tested the seams manual flush and used that before a lot without problems.
Now, I have a long running method which calles other methods and the flush is only called at the end of this long running method.
But however, I can see in my log, that the flush is called randomly - even I do not trigger it by myself. So whats going on?
I definitly use seams manual flush-option and can see that the flush is for example called before using a createNamedQuery to get results from the database. How can I really enforce that flush is only called when I call entityManager.flush() ?
Does Seam automatically calls flush if memory is close? Or are their any limitations when manualFlush does not work??
-
5. Re: Does Seams entityManager disturbs TransactionAttributes in EJB ?
nimo22 Mar 10, 2010 11:54 AM (in response to nimo22)Okay I found the problem:
3.9. Flush the persistence context
3.9.1. In a transaction
From time to time the entity manager will execute the SQL DML statements needed to synchronize the data store with the state of objects held in memory. This process, flush, occurs by default (this is Hibernate specific and not defined by the specification) at the following points:
- before query execution
- from javax.persistence.EntityTransaction.commit()
- when EntityManager.flush() is calledI have indeed some queries within my long span method and before query excecution, Hibernate forces a flush even Seams flush-Mode is manual.
So how can I avoid that? Should I use UserTransaction to ensure that the commit is only called once? I need to ensure that all updates and inserts of a method lies in exactly one transaction.
-
6. Re: Does Seams entityManager disturbs TransactionAttributes in EJB ?
nimo22 Mar 10, 2010 12:10 PM (in response to nimo22)The only interesting question is:
Does JPA/Hibernate ensures that a rollback really rollbacks ALL flushed datas?For example:
@Stateless @Name("myBean") public class EJBBean{ @Resource private SessionContext context; // Here begins the transaction?! public void update(){ this.updateUser(); } public void updateUser(User u) { u.setName("test"); // flush is called automatically because of a query (according to hibernate docs) ! List<Hobby> hobbies= (List<Hobby>) entityManager.createNamedQuery(...); if(updateYes) this.end(); if(updateNo) context.setRollbackOnly(); } public void end() { entityManager.flush(); } }