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(a)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(a)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(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/hibernate-dev
>