You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomee.apache.org by Alexis KRIER <by...@hotmail.com> on 2012/04/12 18:15:38 UTC

can't persist value in TransactionSynchronizationRegistry

Hello all I have an entityManagerProvider wich creates the entityManager if it does not exist already.

To do this I store the EntityManager created in TransactionSynchronizationRegistry 
 TransactionSynchronizationRegistry registry = (TransactionSynchronizationRegistry)getContext().lookup(
          "java:comp/TransactionSynchronizationRegistry");
(works also with java:openejb)

then when an other call is done to the EMProvider I look in the registry to get my manager if it exists:
TransactionSynchronizationRegistry registry = (TransactionSynchronizationRegistry)getContext().lookup(
          "java:comp/TransactionSynchronizationRegistry");
registry.getesources("The key")

The problem is that on each call from a stateless resource, it seem that the registry is always empty...

By the way the registry.put("My entity") is working well because when I do immediately after a get I can see My value stored.

Is there a trick to keep the TransactionSynchronizationRegistry Statefull?

thank you

Alexis
 		 	   		  

Re: can't persist value in TransactionSynchronizationRegistry

Posted by Romain Manni-Bucau <rm...@gmail.com>.
if you use an EJBContainer and call the method close on it it should be
done.

If you start openjeb with an InitialContext you should set the property
openejb.embedded.initialcontext.close
to destroy and call close on the initial context after your tests.

- Romain


2012/4/18 bodtx <al...@infotel.com>

> Ok the problem is found
> We have dbunit which uses the connection pool.
> it creates BasicDataSource & BasicManagedDataSource
> In the method destroy in org.apache.openejb.assembler.classic.Assembler
> closes only resources of type ResourceAdapter
>
> so we've created a method at the end of the use of the openejb instance
> which closes also BasicDataSource & BasicManagedDataSource from the
> assembler.
>
> thanks for help
>
> Alexis
>
> --
> View this message in context:
> http://openejb.979440.n4.nabble.com/can-t-persist-value-in-TransactionSynchronizationRegistry-tp4552345p4567670.html
> Sent from the OpenEJB User mailing list archive at Nabble.com.
>

Re: can't persist value in TransactionSynchronizationRegistry

Posted by bodtx <al...@infotel.com>.
Ok the problem is found
We have dbunit which uses the connection pool.
it creates BasicDataSource & BasicManagedDataSource
In the method destroy in org.apache.openejb.assembler.classic.Assembler 
closes only resources of type ResourceAdapter

so we've created a method at the end of the use of the openejb instance
which closes also BasicDataSource & BasicManagedDataSource from the
assembler.

thanks for help

Alexis

--
View this message in context: http://openejb.979440.n4.nabble.com/can-t-persist-value-in-TransactionSynchronizationRegistry-tp4552345p4567670.html
Sent from the OpenEJB User mailing list archive at Nabble.com.

Re: can't persist value in TransactionSynchronizationRegistry

Posted by bodtx <al...@infotel.com>.
Ok our last message was not sent to this mailing list so here we are:
/
*ME*
 
Wow ok, thanks for the answer.
So I understand a bit more:
So, first our code is not a so good idea. I thought we would get the
connection as a connection pool would do and not the transaction as you've
said...
 and so we have a second problem, once created this connection is never
released even after the hibernate close() call.
I thought creating entitymanager and number of connection created was
linked, but maybe there is something else in here.
 Thank you for your reply


*YOU*

Sounds like you might have configured datasources outside the view of the
container. Common wrong turn is to configure connection information
(drivers, db url, user, pass) in the persistence.xml. This will bypass all
of the connection pooling provided by the container and you can easily get
leaks.

If you configure your datasource like so:
 http://openejb.apache.org/configuring-datasources.html
Then in your persistence.xml just point to the datasource via
<jta-data-source> and <non-jta-data-source>, then all should be good.

Hope this helps!
-David/

So in hibernate manual i've seen this as you've said:
/The following properties can only be used in a SE environment where no
datasource/JNDI is available:

    javax.persistence.jdbc.driver: the fully qualified class name of the
driver class

    javax.persistence.jdbc.url: the driver specific URL

    javax.persistence.jdbc.user the user name used for the database
connection

    javax.persistence.jdbc.password the password used for the database
connection/

our persistence.xml doesn't define that, all is defined externally with
properties
and set int openejb properties:
props.put(ds, "new://Resource?type=DataSource");
    props.put(ds + ".JdbcDriver", helper.getDriver());
    props.put(ds + ".JdbcUrl", url);
    props.put(ds + ".UserName", user);

Is there a way to monitor with jmx connection the openEJB pool?, i've
launched jconsole but I can monitor the EJB pool but that's all.

thank you



--
View this message in context: http://openejb.979440.n4.nabble.com/can-t-persist-value-in-TransactionSynchronizationRegistry-tp4552345p4561697.html
Sent from the OpenEJB User mailing list archive at Nabble.com.

Re: can't persist value in TransactionSynchronizationRegistry

Posted by David Blevins <da...@gmail.com>.
This kind of EntityManager tracking is provided out of the box for you and is a standard part of JavaEE.  In fact it's one of the main benefits you get.  EntityManagers are tracked in a transaction and flushed or discarded on commit or rollback, all automatically.

This doc talks about how it works:  

 - http://openejb.apache.org/jpa-concepts.html

Maybe also see the "JPA Integration" section of this answer which describes the tracking more tersely:

 - http://stackoverflow.com/questions/269186/besides-ear-and-ejb-what-do-i-get-from-a-j2ee-app-server-that-i-dont-get-in-a/9199893#9199893

So the question at hand, if your mechanism for tracking and the container's mechanism for tracking are the same, then why doesn't it work?  The answer applies to both.

The TransactionSynchronizationRegistry (and therefore the EntityManager tracked in it) only live as long as the transaction lives.  That will be for the duration of the one method call if the EJB is being called from someplace that doesn't already have a transaction in progress.

The only way to keep the TransactionSynchronizationRegistry around is to keep the transaction open longer.  There are some things to keep in mind:

   - Transactions are not multi-threaded
   - The transaction must end in the same thread in which it was began

As an FYI, those restrictions are not artificial.  Multi-threaded transactions are hard and there aren't any TransactionManagers that support it -- read, there's no way to get around it.

Your only option for truly holding an EntityManager for a long period of time is to track it between transactions.  The JavaEE standard term for this kind of tracking is called an EXTENDED PersistenceContext.  This example isn't really documented, but the code works and uses EXTENDED persistence contexts.

  http://openejb.apache.org/examples-trunk/injection-of-entitymanager/README.html

EXTENDED persistence contexts provide the same transactional exclusivity and tracking that a TRANSACTION scoped persistence context provides, but with the added benefit that the EntityManager itself will live as long as the @Stateful bean that created it.  You can track the @Stateful bean however you want, such as by putting it into the HttpSession.

Hope this helps!


-David


On Apr 12, 2012, at 9:15 AM, Alexis KRIER wrote:

> 
> Hello all I have an entityManagerProvider wich creates the entityManager if it does not exist already.
> 
> To do this I store the EntityManager created in TransactionSynchronizationRegistry 
> TransactionSynchronizationRegistry registry = (TransactionSynchronizationRegistry)getContext().lookup(
>          "java:comp/TransactionSynchronizationRegistry");
> (works also with java:openejb)
> 
> then when an other call is done to the EMProvider I look in the registry to get my manager if it exists:
> TransactionSynchronizationRegistry registry = (TransactionSynchronizationRegistry)getContext().lookup(
>          "java:comp/TransactionSynchronizationRegistry");
> registry.getesources("The key")
> 
> The problem is that on each call from a stateless resource, it seem that the registry is always empty...
> 
> By the way the registry.put("My entity") is working well because when I do immediately after a get I can see My value stored.
> 
> Is there a trick to keep the TransactionSynchronizationRegistry Statefull?
> 
> thank you
> 
> Alexis
>