I realized that ComponentType#isEqual as well as #isSame, #compare,
#isDirty, and #isModified do not treat empty composites as equivalent to
null in the following cases:
1) the composite has a primitive attribute;
2) the composite has a singular attribute that gets initialized to a
non-null (or non-default primitive) value when the composite is constructed;
3) the composite has a plural attribute.
It would be straightforward to compare a primitive value in a composite
value with the default for the primitive type (e.g, comparing an int
property value with 0 instead of null).
I think it is reasonable to have Hibernate assume that a composite with
Object attributes set to null and primitive values set to its default value
to be considered an empty composite.
I am a little concerned that a primitive value that happens to be set to
the default could be a "real" value intended to be persisted, so I would
like to propose logging a warning
when hibernate.create_empty_composites.enabled=true and a composite has a
primitive value. The message would mention the ambiguity and recommend
using a non-primitive attribute instead.
Regarding 2), here are some examples of a singular attribute initialized to
a non-null (or non-default primitive) value when the composite is
boolean isAvailable = true;
Integer length = -1;
Date created = new Date();
double random = Math.random();
IMO, Hibernate should throw an exception when
hibernate.create_empty_composites.enabled=true, because empty composites,
by definition, should have attributes that correspond to null columns.
At the very least, Hibernate should not automatically inject an
instantiated composite with initialized values when composite columns are
Regarding 3), if a composite contains a plural attribute, Hibernate
automatically injects a PersistentCollection into the empty composite.
ComponentType#isEqual, #isSame, #compare, #isDirty, and #isModified do not
take this into account when comparing the empty collection value with null.
IMO, this should be fixed. ComponentType#isEqual, #isSame, #compare,
#isDirty, and #isModified, should all assume an empty collection is
equivalent to null.
I suppose it could be helpful to add support for custom strategies for
determining if an instantiated composite is empty. For example, a strategy
could disregard some attributes (e.g., dates, random numbers), or have it's
own criteria for what an empty composite is. The default would be check all
attributes in the composite equal to null, primitive default, or empty
collection. I have no plans to pursue at this point though.
Anyone have any comments on any of this?
hibernate-dev mailing list