Michael Dick wrote:
On Fri, Jul 24, 2009 at 6:50 AM, Pinaki Poddar <[email protected]> wrote:
Depends what the bootstrap assume about the providers :
well behaved (they will log their failure before throwing an exception)
-- that is the optimistic view
or not so well behaved (i.e. they simply throw exception) -- that is the
pessimistic view.
For a bootstrap class, a pessimistic world view help, imo.
Agree, but it's up to the spec provider to determine how they handle it.
Introducing a new logging mechanism is up to the Geronimo folks (I'm staying
out of it).
No logging for now, as we want to keep the spec apis logging/framework
neutral and not waste time on something the providers should be logging.
The JPA provider should also take a pessimistic view and not rely on any
unspec'ed behavior in the Persistence class either. Throwing an exception at
this time can prevent other providers from being tried. Thus this is a bug
in OpenJPA.
Agree, and I added a new log call in PersistenceProviderImpl to address
this, but always returning null is beyond the scope of OPENJPA-1076, so
I'll open a new JIRA and keep the current behavior for now, given the
potential junit and end user impacts.
If the bootstrap swallows the exception for provider A without logging,
finds provider B and returns it,
the deployer will have a hard time to fathom why provider A is not loading.
The reason of not logging because "we currently do not require a log
provider" may be good for explanation, but it does not really help anybody.
This is an interesting issue. Should the persistence class be expected to
catch and log runtime exceptions from the persistence provider? Checked
exceptions should be handled, naturally, but unchecked exceptions can ripple
up. The provider should not disrupt further processing unless it has a good
reason to do so.
Consider the case that you originally mentioned. Someone has configured
"openjpa.Specifcation=3.0" in a persistence.xml file and deployed. The
environment has OpenJPA as the only provider. Now the bootstrap calls
OpenJPA, OpenJPA throws exception, the bootstrap swallows the exception,
and
returns null. What will the deployer do to diagnose the error? In fact
instead of helping, the bootstrap effectively made the situation worse by
hiding the informative exception thrown by the provider. Why? because such
and such spec said so or did not say we have to log.
I think OpenJPA should not be throwing an exception in this case. Rather it
should log and return null - OpenJPA should take a pessimistic view of the
support provided by javax.persistence.Persistence, as you put it. Throwing
the exception is helpful this version of OpenJPA is the only persistence
provider available, but causes problems when multiple providers are used.
My gut feel is that PersistenceProviders should avoid these exceptions
except for fatal conditions that stop all providers from functioning. Absent
information in the spec the provider cannot rely on
javax.persistence.Persistence to handle exceptions gracefully. Therefore I'd
prefer us to allow processing to continue - using OpenJPA's log mechanism to
present information to the user. I'd expect other PersistenceProviders to do
the same - if they can't satisfy the request they should get out of the way
and let us have a crack at it :-).
For now (as of Rev798667 of the artifacts published as
geronimo-jpa_2.0_spec-1.0-EA5-20090728.191318-9) the spec api will "eat"
returned exceptions if more than one provider is found, but will
continue to return exceptions to the caller if only one provider was
found or no providers could handle the PU.
> as the way I read the spec is the *first* provider that creates
an EMF should be the one that gets returned.
The operative word is *first*. Who is the *first* provider?
Whichever way you may define *first* case, cutting the search at the first
available provider is unfair policy.
The spec does say though that no order is implied in the list of providers.
Agree, no order is documented, thus we are left with the order they are
presented to us by the classloader (arguably under the user's control).
Agree, and the app/user should set the javax.persistence.provider
property in persistence.xml or as a createEMF() property if they want to
"try" and force a provider.
a javax.persistence.provider property on the createEMF call,
which should effective make that the only provider that should try to
create a EMF
The case that a bootstrap must defend against is where the property is not
specified.
Even if the property is specified, but a provider A who happens to be
*first* returns a
non-null EMF, while the javax.persistence.provider actually points to the
next provider B,
what will be the fair behavior : to return A or B?
I'd vote for returning A. If I've understood the scenario correctly, there
are two instances of the same provider on the classpath. The bootstrap class
has no way to determine the correct one. Ideally the bootstrap class will
log the condition, but such behavior is not required by the spec and should
not be relied upon.
Also, I don't see it as
the javax.persistence.Persistence impls job to cache and free these EMFs
(nothing in the spec suggests this behavior.)
And i do not see why one needs to cache *local* variables or free them to
get a robust behavior.
s/cache/retain references to/
Managing a list of EMFs in the createEMF method is not discussed in the
spec. I think that's Donald's point anyway.
The bottom line (to me anyway) is that OpenJPA cannot assume certain
behavior on the part of javax.persistence.Persistence beyond what is
indicated in the spec.
-mike
DWoods wrote:
Pinaki Poddar wrote:
The bootstrap should ask all (say N) available providers to createEMF().
If any of them throws exception or return null, the bootstrap should
continue asking rest of the providers.
After all N provides have been queried by the bootstrap, let us say M
providers have returned a valid EMF.
1. Log exceptions or null, as the case may be, for each of the (N-M)
failed
providers to give a deployer a chance to know what went wrong.
We currently do not require a log provider for the Geronimo Specs, as
you have no idea what logging will be in place (Log4j, SLF4J, JDK, OSGi,
.....) Since the spec says to return null and doesn't define an
exception to throw, it should be up to the providers to log why they
couldn't create an EMF.
2. if (M == 1)
return the only good one.
else if (M > 1)
tricky. Non-partisan approach will be to throw exception explaining
that
providers are behaving badly.
Disagree, as the way I read the spec is the first provider that creates
an EMF should be the one that gets returned. Also, I don't see it as
the javax.persistence.Persistence impls job to cache and free these EMFs
(nothing in the spec suggests this behavior.) I would rather we ask the
expert group for clarification, than create a nightmare for us to test.
Partisan behavior will be to return OpenJPA provider, if exists. If
not
the first one (unfair, because *first* is ambiguous/non-deterministic).
else // M = 0
return null or throw exception
The key points are
a) robust: not to let one *failed* provider spoil the chance of other
good
ones
agree
b) fair: not to prefer one provider over another (slight bias towards
OpenJPA is OK:). This will address the case of more than one provider
returning non-null EMF. Also do not return immediately at the first
non-null
EMF. Because the ordering on provider is inherently non-deterministic
due
to
the nature of the discovery process.
don't see this as a problem, as 1) the spec defines support for
providing a javax.persistence.provider property on the createEMF call,
which should effective make that the only provider that should try to
create a EMF, 2) we could look at the discovered list of persistence
providers and try loading ours first.
c) helpful: provide as much contextual info as possible for diagnosis
(the
deployer/developer will be pleased)
again, see this as the job of each provider, to log why they could not
return a valid EMF (since they have to handle logging in JSE, JEE and
OSGi today)
So if OpenJPA is throwing exception on unsupported openjpa.Specification
property value, let it continue to do so. Others may return null under
certain circumstances, or throw exception in another.
Absorb the provider implementation variations in the bootstrap.
-----
Pinaki
-----
Pinaki
--
View this message in context:
http://n2.nabble.com/JPA2---When-should-createEMF%28%29-return-an-Exception-vs.-NULL--tp3312130p3315250.html
Sent from the OpenJPA Developers mailing list archive at Nabble.com.