[hibernate-dev] Unsaved values
Steve Ebersole
steve at hibernate.org
Fri Mar 30 11:08:20 EDT 2012
unsaved-value is tricky in many ways. In case anyone is not aware,
there really is just one unsaved-value strategy for each entity. It
just happens that unsaved determination could be based on id, or based
on version; that is why we have 2. Outside of an explicitly
user-provided value, "undefined" at the id level should result in using
the version-based strategy. "undefined" simply means that Hibernate is
supposed to physically go query the database to determine if that
particular id value already exists (detached) or not
(transient/unsaved). The end goal is to avoid that as often as
possible.
I am pretty sure that all "assigned" generators[1] default to
"undefined" as the id-based unsaved-value. I am certain that is the
case with HBM. I would think that is the desired behavior with
annotations as well. Again, this is outside of the user explicitly
providing an unsaved-value.
EntityBinder.wrapIdsInEmbeddedComponents() is dealing with what
Hibernate used to call "embedded composite ids" way before JPA came
along and misused that term :) Basically the notion of an entity that
defines a composite identifier but does not use a component to
represent the id value. It is setting that flag whenever it processes
an entity that does not define an @IdClass.
Anyway, my gut tells me that any differences between annotations and
hbm in terms of unsaved-value are due to code duplication rather than a
conscious decision to have them be different.
[1] and all composite ids are typically "assigned", unless the user
specifies generator for the component. I forget offhand how "partial
generation" of composite ids are viewed in terms of generator, but my
guess is that they are always deemed "assigned".
On Thu 29 Mar 2012 07:12:40 PM CDT, Gail Badner wrote:
> From digging into the code, it looks like the only place where things may need to be processed differently is for composite/component IDs.
>
> o.h.mapping.SimpleValue.nullValue is initialized to null.
>
> There are 2 places in the old mapping code where SimpleValue.setNull( "undefined" ) is called when binding from annotations:
> - in o.h.cfg.BinderHelper.makeIdGenerator(), if the generator is "assigned" [1]
> - in o.h.cfg.annotations.PropertyBinder.bind(), if isXToMany or entityBinder.wrapIdsInEmbeddedComponents() are true [2].
>
> I believe isXToMany is true if the ID is actually a many-to-one (like HBM key-many-to-one). It makes sense to me that the unsaved value would be "undefined" in this case. The same is true for HBM key-many-to-one, unless some other unsaved-value is specified, so there's no inconsistency there.
>
> I'm not sure of the use cases where entityBinder.wrapIdsInEmbeddedComponents() is true.
>
> An inconsistency with HBM could arise if the generator is not "assigned" and both isXToMany and entityBinder.wrapIdsInEmbeddedComponents() are false for a use case that corresponds with an HBM composite-id.
>
> Can that happen? If so, the unsaved value for annotations would end up as null and the unsaved value for HBM would be "undefined" (unless some other value was specified).
>
> [1] https://github.com/hibernate/hibernate-orm/blob/metamodel/hibernate-core/src/main/java/org/hibernate/cfg/BinderHelper.java#L526
>
> [2] https://github.com/hibernate/hibernate-orm/blob/metamodel/hibernate-core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java#L218
>
> ----- Original Message -----
>> From: "Steve Ebersole"<steve at hibernate.org>
>> To: "Gail Badner"<gbadner at redhat.com>
>> Cc: "Hibernate hibernate-dev"<hibernate-dev at lists.jboss.org>
>> Sent: Thursday, March 29, 2012 8:51:13 AM
>> Subject: Re: [hibernate-dev] Unsaved values
>>
>> I'll definitely take a look as soon as I get some time (currently
>> busy
>> working through some JPA 2.1 stuff). But in the meantime maybe you
>> could do a plain English write-up describing the differences you see
>> here between hbm and annotations that led you to look to these
>> strategies so that we can comment and get you moving forward more
>> quickly...
>>
>> In general, the thing we need to guard against here is duplicating
>> code. The existing binders duplicate tons of stuff and its a
>> maintenance nightmare. So for example, the end-game determination
>> for
>> unsaved-value in hbm is to instantiate the entity an reflect its
>> actual
>> newly-instantiated value. I think annotations does the same. So
>> that
>> code should be outside of hbm/annotations. Unless we decide as a
>> group
>> that its "ok" for sources (hbm/annotations) to share that code
>> (subclass, delegation, etc) from its particular strategy.
>>
>> On Thu 29 Mar 2012 02:25:35 AM CDT, Gail Badner wrote:
>>> At the team meeting in Austin, I remember discussion about cases
>>> where different "strategies" were needed to process values
>>> obtained from annotations and hbm.xml sources. I can't remember if
>>> we discussed unsaved values, but it seems to me that this is one
>>> case where this is needed.
>>>
>>> I created a pull request for dealing with unsaved values:
>>> https://github.com/hibernate/hibernate-orm/pull/298.
>>>
>>> Please take a look and provide feedback to let me know if I'm on
>>> the right track.
>>>
>>> Thanks,
>>> Gail
>>> _______________________________________________
>>> hibernate-dev mailing list
>>> hibernate-dev at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>
>> --
>> steve at hibernate.org
>> http://hibernate.org
>>
--
steve at hibernate.org
http://hibernate.org
More information about the hibernate-dev
mailing list