[hibernate-dev] Null vs "empty" embeddable values
Gail Badner
gbadner at redhat.com
Wed Jul 26 19:45:52 EDT 2017
IIUC, the fix for HHH-7610 was supposed to have Hibernate treat null and
empty composite as equivalent, regardless of how
hibernate.create_empty_composites.enabled
is set. [1]
The application could instantiate empty embeddables itself, and Hibernate
should still treat those values as equivalent to null.
Is it really enough to check that the composite overrides equals/hashCode
(without actually finding out if (!emptyValue.equals( null ) ||
emptyValue.hashCode() != 0)?
I think documentation would help.
[1] https://github.com/hibernate/hibernate-orm/pull/1080
On Wed, Jul 26, 2017 at 4:21 PM, Steve Ebersole <steve at hibernate.org> wrote:
> No I mean checking on start up similar to what we do for composite id
> classes. So basically if this setting is enabled (treat all nulls == empty
> composite) make sure that the composite overrides equals/hashCode.
>
>
>
> On Wed, Jul 26, 2017 at 6:08 PM Gail Badner <gbadner at redhat.com> wrote:
>
>> Hi Steve,
>>
>> IIUC, you are suggesting:
>>
>> if ( !emptyValue.equals( null ) || emptyValue.hashCode() != 0 ) {
>> LOG.warn( ... );
>> }
>>
>> I originally mentioned this issue with respect to Collection methods
>> called on collections of embeddable values, but it could apply to
>> empty/null embeddables in singular attributes as well.
>>
>> This warning would apply regardless of the setting for
>> hibernate.create_empty_composites.enabled, since an application itself
>> could set null or empty embeddable values.
>>
>> After thinking about this more, I suspect that such a warning would get
>> logged for many (most?) embedded values.
>>
>> There is also a complication that Hibernate will inject the parent into
>> an empty value if @Parent is mapped on a property in the embeddable. That
>> (non-empty) parent could affect what gets returned by #equals and/or
>> #hashCode.
>>
>> I've been trying to figure out a good place for checking to minimize the
>> warnings.
>>
>> Here are some options:
>>
>> 1) Check when the owner PersistentClass is being validated by
>> MetadataImpl#validate.
>>
>> Component#validate could be added to override SimpleValue#validate. If
>> the check fails, a warning will logged in each context where the embeddable
>> is used.
>>
>> Unfortunately, if @Parent is used in the embeddable class, there would be
>> no way to check if parent attribute affects #equals or #hashCode since
>> there is (obviously) no parent when validating the PersistentClass.
>>
>> 2) Check after Hibernate instantiates an empty value when resolving a
>> null value with hibernate.create_empty_composites.enabled=true by
>> ComponentType#resolve(Object value, SharedSessionContractImplementor
>> session, Object owner).
>>
>> I believe the parent would be provided to the method, so it would be
>> available to check. I'd have to check to be sure though.
>>
>> If the parent contributes to the return values of #equals or #hashCode,
>> there are other considerations to take into account.
>>
>> At the time ComponentType#resolve is called, the parent may not be
>> completely resolved; it may not be valid to call those methods when the
>> component is being resolved.
>>
>> Calling #hashCode and #equals on the parent each time Hibernate
>> instantiates an empty value when resolving a null value (with
>> hibernate.create_empty_composites.enabled=true) could hurt performance.
>>
>> If the check fails, lots of warnings could be logged.
>>
>> My opinion...
>>
>> After thinking about this as I'm writing this, I think 1) makes sense if
>> there is no parent; 2) has too many problems to be workable.
>>
>> Any other ideas about how to deal with this?
>>
>> I don't think there is anything in the user guide that discusses how
>> Hibernate treats null and empty embeddables as equivalent. There have been
>> issues reported periodically related to collections. The most recent
>> is HHH-11723. I think it would be worthwhile documenting this
>> information in the user guide.
>>
>> Comments?
>>
>> Thanks,
>> Gail
>>
>> On Wed, Jul 26, 2017 at 6:01 AM, Steve Ebersole <steve at hibernate.org>
>> wrote:
>>
>>> "Requirement" - no. I think a warning in this case is perfectly fine.
>>>
>>> As for JPA, it says nothing about embeddables and nulls.
>>>
>>> On Sun, Jul 23, 2017 at 6:49 PM Gail Badner <gbadner at redhat.com> wrote:
>>>
>>>> As of HHH-7610, Hibernate is supposed to treat null and empty embeddable
>>>> values as equivalent.
>>>>
>>>> Should we add a requirement that an embeddable class #equals and
>>>> #hashCode
>>>> methods also treats null and "empty" values as equivalent?
>>>>
>>>> That would mean that #hashCode returned for all empty embeddables
>>>> should be
>>>> 0, and embeddableValue.equals( null ) should return true for all empty
>>>> embeddableValue.
>>>>
>>>> BTW, I've already pushed a fix for HHH-11881 so that nulls are not
>>>> persisted for Set elements (they already were not persisted for bags,
>>>> idmaps, lists, or maps). I'm holding off on fixing HHH-11883, which
>>>> would
>>>> no longer persist empty embeddable values and would ignore embeddables
>>>> with
>>>> all null columns when initializing collections.
>>>>
>>>> I don't think JPA has any such requirement, and I'm hesitant to enforce
>>>> something that may be at odds with JPA.
>>>>
>>>> Comments or opinions?
>>>>
>>>> Thanks,
>>>> Gail
>>>> _______________________________________________
>>>> 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