[hibernate-dev] JPA Compliance

Vlad Mihalcea mihalcea.vlad at gmail.com
Tue Nov 28 06:18:52 EST 2017


Makes sense. I think it's reasonable to add this since this is what a
many-to-many table relationship looks like.

But, it's ok to postpone it until 6.0.

Vlad

On Tue, Nov 28, 2017 at 12:38 PM, andrea boriero <andrea at hibernate.org>
wrote:

> It is not about the order but about duplicates.
>
> With the following
> class A {
>        List<b> bsl
> @JoinTable(name = "A_B",
>         joinColumns = @JoinColumn(name = "A_ID"),
>         inverseJoinColumns = @JoinColumn(name = "B_ID"),
> )
> @ManyToMany
> public List<B> getBs() {
> return b;
> }
> }
>
> class *B*{
> List<A> as;
> ....
> @ManyToMany(mappedBy = "bs", cascade=CascadeType.ALL)
> public List<A> getAs() {
> return as;
>  }
> }
>
> and it seems JPA expects the JoinTable A_B to have a PK (A_ID,B_ID).
>
> On 28 November 2017 at 05:44, Vlad Mihalcea <mihalcea.vlad at gmail.com>
> wrote:
>
>> I don't understand what is the requirement for the @Bag annotation and
>> the  `hibernate.jpa.compliance=list` setting.
>>
>> From the JPA spec, only if we provide @OredrBy or @OrderColumn we get an
>> ordered List.
>> Otherwise, the order is undefined.
>> Is there anything I'm missing about handling Lists according to the JPA
>> spec?
>>
>> Vlad
>>
>> On Mon, Nov 27, 2017 at 11:29 PM, Steve Ebersole <steve at hibernate.org>
>> wrote:
>>
>>> So then how about the following:
>>>
>>>
>>>    1. Add a multi-valued setting to define various categories of JPA
>>>    compliance.  E.g. `hibernate.jpa.compliance` with multi-selectable values
>>>    such as:
>>>    1. query (strict jpql compliance)
>>>       2. txn (transaction handling per spec)
>>>       3. close (multiple calls to EMF and EM #close methods)
>>>       4. list (no bags)
>>>       5. others?
>>>       6. all (there should be some form of specifying all)
>>>    2. Add @Bag as an explicit declaration of a bag, even if
>>>    `hibernate.jpa.compliance=list` is specified - that setting just
>>>    controls how List with no @OrderColumn is interpreted.  I vote to delay
>>>    adding that until 6.0
>>>    3. Retain current behavior for "double close" calls unless "close"
>>>    compliance has been specified.
>>>    4. Keep current behavior unless "txn" compliance has been specified
>>>
>>>
>>>
>>> On Mon, Nov 27, 2017 at 4:54 AM andrea boriero <andrea at hibernate.org>
>>> wrote:
>>>
>>>> On 24 November 2017 at 17:39, Steve Ebersole <steve at hibernate.org>
>>>> wrote:
>>>>
>>>>> Andrea, SF is a EMF.  Unwrapping simply returns the same instance.
>>>>>
>>>>
>>>> yes but has you pointed out due to the bootstrapping the behaviour of
>>>> the SF will be strict JPA compliant.
>>>>
>>>>>
>>>>> Another thing I was discussing with Andrea in chat is possibly making
>>>>> these multi-valued, or having multiple values for this.  I can't imagine
>>>>> the FQN case is really all that appealing to a user.  I'm fairly certain a
>>>>> user would rather simply say "yeah, treat transactions according the JPA
>>>>> spec" as opposed to "here is a class I will provide that will tell will
>>>>> treat transactions according to the JPA spec".
>>>>>
>>>>> We have started to identify some cases where we deviate from the
>>>>> spec[1], such as:
>>>>> * Strict query compliance.  As I mentioned earlier we do have such a
>>>>> setting already for this in particular
>>>>> * List versus Bag determination from mappings.
>>>>> * Closed EMF (SF) handling
>>>>> * EntityTransaction status checking - JPA says we should throw
>>>>> exceptions whereas we just ignore the call.
>>>>>
>>>>> We need to decide also which of these we want to just change outright
>>>>> versus controlling via a setting.
>>>>>
>>>>> * Setting
>>>>> * Setting, or introduce a new @Bag annotation - the annotation option
>>>>> is actually pretty appealing since often times the bag behavior is so
>>>>> unexpected from users...
>>>>>
>>>>
>>>> @Bag seems really a good idea to me but that means changing the current
>>>> default behaviour, forcing users to change the code, so not sure if we need
>>>> also a setting.
>>>>
>>>>
>>>>> * I think we should just change the behavior of calling EMF#close on a
>>>>> closed EMF.  Any application that happens to be relying on us no-op'ing
>>>>> this call can easily change that to protect the call with an `#isOpen`
>>>>> check.  In fact I think we should change all of these to match the JPA
>>>>> expectations such that it is an error to call any of the following: #close,
>>>>> #getCache, #getMetamodel, #getCriteriaBuilder, #getProperties,
>>>>> #getPersistenceUnitUtil, #createEntityManager.  To me these all seem pretty
>>>>> reasonable.  And in fact I think we used to handle this all properly from
>>>>> the EMF side.  I think we just lost that behavior when we changed to have
>>>>> our contracts extend the JPA ones since we kept the legacy Hibernate
>>>>> behavior in SessionFactory.
>>>>>
>>>>
>>>> I do not like the EMF#close behaviour, probably a prefer a separate
>>>> setting for this.
>>>>
>>>>
>>>>> * This one I am very undecided.  I can see very valid arguments for
>>>>> each.
>>>>>
>>>>
>>>> probably for such case a setting may be a good option.
>>>>
>>>>>
>>>>> [1] we really ought to start keeping a list of these.  I have started
>>>>> adding them to the migration guide.  Just as a list of things we need to
>>>>> support configuring or switch to the JPA "way".
>>>>>
>>>>> On Fri, Nov 17, 2017 at 11:06 AM andrea boriero <andrea at hibernate.org>
>>>>> wrote:
>>>>>
>>>>>> I think for 5.3 it's still fine to rely on isJpaBootstrap may be
>>>>>> documenting that a SF obtained  from unwrapping an EMF will conform to the
>>>>>> JPA spec in term of exceptions.
>>>>>>
>>>>>> On 16 November 2017 at 21:09, Vlad Mihalcea <mihalcea.vlad at gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>>> When I said multiple modes, I was thinking of defining all these
>>>>>>> situations
>>>>>>> In some interface which declares methods like:
>>>>>>>
>>>>>>> boolean throwsExceptionWhenClosingAClosedEMF()
>>>>>>>
>>>>>>> The interface can have two implementations for Strict JPA and Native
>>>>>>> mode.
>>>>>>>
>>>>>>> However, the setting could take the FQN of the interface
>>>>>>> implementation, so
>>>>>>> a user can define those compatibility methods according to their
>>>>>>> needs.
>>>>>>>
>>>>>>> E.g. Maybe someone wants the Strict JPA mode but with just 2
>>>>>>> differences;
>>>>>>>
>>>>>>> - don't throw exception when closing the ENG twice
>>>>>>> - use the native Hibernate FlushMode.AUTO instead of the JPA one.
>>>>>>>
>>>>>>> Vlad
>>>>>>>
>>>>>>> On 16 Nov 2017 10:49 pm, "Steve Ebersole" <steve at hibernate.org>
>>>>>>> wrote:
>>>>>>>
>>>>>>> > There is already a similar setting, although specific to query
>>>>>>> language:
>>>>>>> > `hibernate.query.jpaql_strict_compliance` - so there is
>>>>>>> precedence for
>>>>>>> > such a solution.
>>>>>>> >
>>>>>>> > I'm not sure about the "with multiple modes" aspect though.  What
>>>>>>> are
>>>>>>> > these other enumerated mode values?
>>>>>>> >
>>>>>>> >
>>>>>>> > On Thu, Nov 16, 2017 at 2:15 PM Vlad Mihalcea <
>>>>>>> mihalcea.vlad at gmail.com>
>>>>>>> > wrote:
>>>>>>> >
>>>>>>> >> Where the JPA way is questionable, let's add one configuration:
>>>>>>> >> hibernate.jpa.compliance with multiple modes:
>>>>>>> >>
>>>>>>> >> - strict: we do whatever the JPA standard says we should do, like
>>>>>>> >> throwing an exception when trying to close the EMF twice
>>>>>>> >> - native: we bend the rule where we don't agree with the standard
>>>>>>> >>
>>>>>>> >> Maybe we should expose all those cases and group them in some
>>>>>>> interface
>>>>>>> >> to allow the user to customize the level of compliance they need.
>>>>>>> >>
>>>>>>> >> Vlad
>>>>>>> >>
>>>>>>> >> On Thu, Nov 16, 2017 at 10:06 PM, Steve Ebersole <
>>>>>>> steve at hibernate.org>
>>>>>>> >> wrote:
>>>>>>> >>
>>>>>>> >>> It was added deprecated.  Meaning I added it knowing it would go
>>>>>>> away
>>>>>>> >>> and I wanted to avoid users using it.
>>>>>>> >>>
>>>>>>> >>> BTW, I am talking about a 5.3 release specifically covering 5.2
>>>>>>> + JPA
>>>>>>> >>> 2.2.  Yes there is a longer term aspect as well with 6.0 and
>>>>>>> beyond.
>>>>>>> >>>
>>>>>>> >>> Its specifically the "where the JPA way is questionable" aspect
>>>>>>> I am
>>>>>>> >>> asking about.  Like to me, it really never makes sense to throw
>>>>>>> an
>>>>>>> >>> exception when I close something that is already closed. So how
>>>>>>> do we
>>>>>>> >>> handle cases like this?
>>>>>>> >>>
>>>>>>> >>>
>>>>>>> >>> On Thu, Nov 16, 2017 at 1:51 PM Vlad Mihalcea <
>>>>>>> mihalcea.vlad at gmail.com>
>>>>>>> >>> wrote:
>>>>>>> >>>
>>>>>>> >>>> Hi Steve,
>>>>>>> >>>>
>>>>>>> >>>> I think that for 5.2 was ok to have the isJpaBootstrap method
>>>>>>> to avoid
>>>>>>> >>>> breaking compatibility for the native bootstrap.
>>>>>>> >>>> For 6.0, maybe it's easier if we just align to the JPA spec
>>>>>>> where it
>>>>>>> >>>> makes sense,
>>>>>>> >>>> and only provide a separation where the JPA way is questionable.
>>>>>>> >>>>
>>>>>>> >>>> I noticed that the isJpaBootstrap method is deprecated. Was it
>>>>>>> >>>> intended to be removed in 6.0?
>>>>>>> >>>>
>>>>>>> >>>> Vlad
>>>>>>> >>>>
>>>>>>> >>>> On Thu, Nov 16, 2017 at 6:21 PM, Steve Ebersole <
>>>>>>> steve at hibernate.org>
>>>>>>> >>>> wrote:
>>>>>>> >>>>
>>>>>>> >>>>> Part of 5.2 was merging the JPA contracts into the
>>>>>>> corresponding
>>>>>>> >>>>> Hibernate
>>>>>>> >>>>> ones.  So, e.g., we no longer "wrap" a SessionFactory in an
>>>>>>> impl of
>>>>>>> >>>>> EntityManagerFactory - instead, SessionFactory now extends
>>>>>>> >>>>> EntityManagerFactory.
>>>>>>> >>>>>
>>>>>>> >>>>> This caused a few problems that we handled as they came up.  In
>>>>>>> >>>>> working on
>>>>>>> >>>>> the JPA 2.2 compatibility testing, I see that there are a few
>>>>>>> more
>>>>>>> >>>>> still
>>>>>>> >>>>> that we need to resolve.  Mostly they relate to JPA expecting
>>>>>>> >>>>> exceptions in
>>>>>>> >>>>> certain cases where Hibernate has historically been lenient.
>>>>>>> E.g., JPA
>>>>>>> >>>>> says that calling EntityManagerFactory#close on an EMF that is
>>>>>>> already
>>>>>>> >>>>> closed should result in an exception.  Historically, calling
>>>>>>> >>>>> SessionFactory#close on a SF that is already closed is simply
>>>>>>> ignored.
>>>>>>> >>>>> Philosophical debates aside[1], we need to decide how we want
>>>>>>> to handle
>>>>>>> >>>>> this situation such that we can throw the JPA-expected
>>>>>>> exceptions when
>>>>>>> >>>>> needed.  Do we simply change SF#close to match the JPA
>>>>>>> expectation?
>>>>>>> >>>>> Or do
>>>>>>> >>>>> we somehow
>>>>>>> >>>>> make SF#close aware of JPA versus "native" use?  This latter
>>>>>>> option
>>>>>>> >>>>> was the
>>>>>>> >>>>> intent of `SessionFactoryOptions#isJpaBootstrap` and we can
>>>>>>> certainly
>>>>>>> >>>>> continue to use that as the basis of the solution here for
>>>>>>> other cases.
>>>>>>> >>>>>
>>>>>>> >>>>> This `#isJpaBootstrap` flag is controlled by the JPA bootstrap
>>>>>>> code.
>>>>>>> >>>>> So if
>>>>>>> >>>>> the EMF is created in either of the 2 JPA-defined bootstrap
>>>>>>> mechanisms,
>>>>>>> >>>>> that flag is set to true.  It's an ok solution, but it does
>>>>>>> have some
>>>>>>> >>>>> limitations - mainly, there was previously a distinction
>>>>>>> between
>>>>>>> >>>>> SF#close
>>>>>>> >>>>> being called versus EMF#close being called (they were different
>>>>>>> >>>>> classes, so
>>>>>>> >>>>> they could react differently).  Therefore, regardless of
>>>>>>> bootstrap
>>>>>>> >>>>> mechanism, if the user unwrapped the EMF to a SF, they would
>>>>>>> always
>>>>>>> >>>>> get the
>>>>>>> >>>>> legacy SF behavior.
>>>>>>> >>>>>
>>>>>>> >>>>> So long story short, so we want to consider an alternative
>>>>>>> approach to
>>>>>>> >>>>> deciding what to do in "some"[2] of these cases?  Again, we
>>>>>>> clearly
>>>>>>> >>>>> need
>>>>>>> >>>>> these to throw the spec-mandated exceptions in certain "strict
>>>>>>> >>>>> compliance"
>>>>>>> >>>>> situations.  The question really is how to do that.  Should we:
>>>>>>> >>>>>
>>>>>>> >>>>>    1. just completely change the behavior to align with the
>>>>>>> spec?
>>>>>>> >>>>>    2. change the behavior to match the spec *conditionally*,
>>>>>>> where that
>>>>>>> >>>>>    condition could be:
>>>>>>> >>>>>       1. `#isJpaBootstrap`
>>>>>>> >>>>>       2. some setting
>>>>>>> >>>>>       3. some extension contract
>>>>>>> >>>>>       4. something else?
>>>>>>> >>>>
>>>>>>> >>>>
>>>>>>> >>>>>
>>>>>>> >>>>> Thoughts?
>>>>>>> >>>>>
>>>>>>> >>>>>
>>>>>>> >>>>> [1] It's not relevant e.g. that I think JPA is wrong here.  We
>>>>>>> need to
>>>>>>> >>>>> comply with the spec, at least in certain cases ;)
>>>>>>> >>>>>
>>>>>>> >>>>> [2] I say "some" here, because I think the spec is correct in
>>>>>>> some
>>>>>>> >>>>> cases -
>>>>>>> >>>>> for example, I think its clearly correct that a closed EMF
>>>>>>> throws an
>>>>>>> >>>>> exception when `#createEntityManager` is called.  Personally I
>>>>>>> think
>>>>>>> >>>>> its
>>>>>>> >>>>> questionable whether closing an already closed EMF should be an
>>>>>>> >>>>> exception.
>>>>>>> >>>>>
>>>>>>> >>>> _______________________________________________
>>>>>>> >>>>> hibernate-dev mailing list
>>>>>>> >>>>> hibernate-dev at lists.jboss.org
>>>>>>> >>>>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>>>>>> >>>>>
>>>>>>> >>>>
>>>>>>> >>>>
>>>>>>> >>
>>>>>>> _______________________________________________
>>>>>>> hibernate-dev mailing list
>>>>>>> hibernate-dev at lists.jboss.org
>>>>>>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>>>>>>
>>>>>>
>>>>>>
>>
>


More information about the hibernate-dev mailing list