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/...
[2]
https://github.com/hibernate/hibernate-orm/blob/metamodel/hibernate-core/...
----- Original Message -----
> From: "Steve Ebersole"<steve(a)hibernate.org>
> To: "Gail Badner"<gbadner(a)redhat.com>
> Cc: "Hibernate hibernate-dev"<hibernate-dev(a)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(a)lists.jboss.org
>>
https://lists.jboss.org/mailman/listinfo/hibernate-dev
>
> --
> steve(a)hibernate.org
>
http://hibernate.org
>