openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Donald Woods <dwo...@apache.org>
Subject Re: JPA2 - When should createEMF() return an Exception vs. NULL?
Date Tue, 28 Jul 2009 19:49:04 GMT


Michael Dick wrote:
> On Fri, Jul 24, 2009 at 6:50 AM, Pinaki Poddar <ppoddar@apache.org> 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.
>>
> 

Mime
View raw message