Option for injecting empty (non-null) embedded when all columns are NULL
Description
Attachments
causes
is duplicated by
Activity

EricB July 8, 2014 at 6:14 PMEdited
This is probably going to be frowned upon by purists, but until there is a way to configure hibernate to ensure @Embedded fields are non-null, I've written an AspectJ to populate the value if null.
This isn't fully tested, and definitely not tested against Collections of embedded objects, so buyer-beware.
Steve Ebersole October 21, 2013 at 2:42 PM
You would need to add handling to the actual reading of a composite out of the ResultSet to handle all tuples as null to mean "create an empty composite instance". That's how "loaded state" is populated. This would require changing org.hibernate.type.ComponentType#resolve
from:
ComponentType.java
to something like:
ComponentType.java
You'd also need to make certain that this is accounted for in the various equality checking methods (isSame, isEqual, compare, isModified, etc).
Also this will require lots of testing as this is a long standing assumption in Hibernate code.
Ultimately this is very low on my todo list. But if someone wants to work on it and work up a Pull Request, that obviously raises the likelihood that it gets resolved sooner. I laid out the main changes above. Just make sure that createEmptyCompositesEnabled():
delegates to SessionFactory/Settings
is fueled by a user-controlled setting
is disabled by default (opt-in behavior)

Markos Fragkakis October 21, 2013 at 10:06 AM
I am getting the same with Pavel, debugged all the way to ComponentType#hydrate
.

Pavel Horal August 7, 2013 at 9:21 AMEdited
Not sure what have changed since I first tested the workaround, but we have tried to actually implement it in our application and Hibernate again handles everything as "dirty". Loaded state is always "null", new state is always empty entity. So there must be something else to make this workaround work. It does not work as is.
UPDATE: The reason for the non-working workaround is ComponentType#hydrate
, which returns null
if all its properties are null. Thus it is not possible to have non-null loaded entity state.

Pavel Horal July 19, 2013 at 12:25 PMEdited
Unfortunately I am not able to persuade Hibernate to use field access for my embedded object (moving @Embedded to field or adding @AccessType doesn't help). But using common sense it can not work with that.
Also I have a small modification to the workaround - we will use a bit more semantically correct alternative (instead of ignoring null value, we will interpret it as an "empty object"):
When all of the values in an
@Embedded
object areNULL
, Hibernate sets the field in the parent object tonull
. This can lead toNullPointerExceptions
if not handled correctly.There are two ways to handle this:
Make sure code that calls the @Embedded getter handles null return values.
Add a non-nullable field to the embedded object, thus avoiding the behavior entirely.
I suggest to make this optional. I.e. add an annotation which would make Hibernate create an object with it's properties set to
null
.In my oppinion, this would improve usability and user friendliness.
Having an embedded object with all props potentially set to null is perfectly valid use case - e.g. an object with optional traits grouped in
@Embeddable
class; When this is created, the traits are initially empty.This was reported years ago as a bug, but at that time, it was closed as Won't fix for unknown reason.