[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