Thanks for the great info Patrick.
For now, I'm going to leave my implementation the way it is, without
instance reuse, and wait until someone complains loudly.
BTW in CMP there are a several places in the lifecycle of entities
that people like to reuse beans...
1) Beans are created and the ejb context is set into them
2) A primary key is assigned
3) Data is loaded into the bean
People like to reuse instances at all three levels. The solution you
suggest below addresses the first. Would it be possible to hook the
cache to give the OpenJPA system an entity with data already loaded?
Anyway, for not I'm just going to wait and see if anyone deeply cares
about this feature.
Thanks for help,
-dain
On Apr 8, 2007, at 8:56 AM, Patrick Linskey wrote:
Hi,
The easy way to do this is with extended persistence contexts. In an
extended persistence context, your working set of objects lasts for
the
duration of the entity manager, not the transaction.
In a JTA environment, the container is supposed to set things up so
that
EMs are transactional by default. To the best of my knowledge, between
this rule and the persistence context propagation rule, this means
that
the container creates an EM proxy that gets injected / looked up, and
that internally delegates through to the "right" EM internally. (I'm
assuming that you're doing this for your EJB2 container work.)
So, going with an extended PC is probably not sufficient for you,
if you
want to be spec-compliant. One thing that you could do, though, is
make
your EM proxy smart about holding onto a single EM for a long
amount of
time for use in transactions, but only use that EM during
transactions.
This would be closer to spec-compliant behavior, but wouldn't be 100%
there.
The 100% solution would be to change OpenJPA to delegate to a
pluggable
factory for creation of new instances. This would require creating an
interface with the two pcNewInstance() signatures in
PersistenceCapable,
and changing the nine places in code that use that method directly to
call the factory instead.
Then, you could plug in whatever instance pooling logic you prefer,
and
you'd be in good shape. You'd need to figure out some way to know when
to re-pool the instances, but in a container environment, that
shouldn't
be that hard. Note that you wouldn't want to use an
Synchronization.afterCompletion() callback, since if it's detached,
the
instance might be used after completion in a rendering step or
something
of the sort, or it might be tucked away in session state for use later
on.
Of course, if you've got a pluggable instance factory, you'd have some
other alternates as well, such as creating clones or something of the
sort.
Out of curiosity, what is slow about creating your instances?
-Patrick
--
Patrick Linskey
BEA Systems, Inc.
______________________________________________________________________
_
Notice: This email message, together with any attachments, may
contain
information of BEA Systems, Inc., its subsidiaries and
affiliated
entities, that may be confidential, proprietary, copyrighted
and/or
legally privileged, and is intended solely for the use of the
individual
or entity named in this message. If you are not the intended
recipient,
and have received this message in error, please immediately return
this
by email and then delete it.
-----Original Message-----
From: Dain Sundstrom [mailto:[EMAIL PROTECTED]
Sent: Sunday, April 08, 2007 12:18 AM
To: open-jpa-dev@incubator.apache.org
Subject: Can I reuse instances?
Is it possible to reuse instances from transaction to transaction?
I would like to be able to create a bean in one transaction, detach
it and reattach the same instance in a new transaction. My
goal here
is specifically to reuse instances across transactions because they
have a very expensive creation cost, and no I can not redesign the
system.
I tried a quick test case using merge, but merge returned a new
instance:
beginTx();
Employee dain = entityManager.find(Employee.class, dainPk);
assertEquals(dain.getFirstName(), "Dain");
commitTx();
beginTx();
assertSame(dain, entityManager.merge(dain));
assertEquals(david.getFirstName(), "Dain");
commitTx();
When I try to use the refresh method, OpenJPA complains that the
entity "is not managed by this context".
So is there anyway for me to reuse instances?
-dain
Notice: This email message, together with any attachments, may
contain information of BEA Systems, Inc., its subsidiaries
and affiliated entities, that may be confidential, proprietary,
copyrighted and/or legally privileged, and is intended solely for
the use of the individual or entity named in this message. If you
are not the intended recipient, and have received this message in
error, please immediately return this by email and then delete it.