@Embedded object not instantiated automatically if it has no basic datatype fields

For Hibernate, you might want to check out issue HHH-7610.

In particular, since 5.1 there is an experimental feature to change this behavior. Note that this feature has known issues, and should not be used in production until it is stabilized. This is detailed in the Javadocs for org.hibernate.cfg.AvailableSettings):

/**
 * [EXPERIMENTAL] Enable instantiation of composite/embedded objects when all of its attribute values are {@code null}.
 * The default (and historical) behavior is that a {@code null} reference will be used to represent the
 * composite when all of its attributes are {@code null}
 * <p/>
 * This is an experimental feature that has known issues. It should not be used in production
 * until it is stabilized. See Hibernate Jira issue HHH-11936 for details.
 *
 * @since 5.1
 */
String CREATE_EMPTY_COMPOSITES_ENABLED = "hibernate.create_empty_composites.enabled";

Set the hibernate.create_empty_composites.enabled property to true and voilà!


I don't think the JPA spec clearly describes what should happen when an @Embedded object's properties are all null, but at least some implementations treat an object with null properties as a null object, which is what you're seeing.

This seems like a reasonable implementation. Certainly it's been useful in my code (using Hibernate) where if I set an @Embedded object to null I want it to remain null when I load a persisted version.

In your example, the AutoInstantiated class can never be considered null, since the primitive property theKey can never be null.


I just hit the same issue with Hibernate. The original question, about the "why" is answered.

But to talk about a solution, I just use a @PostLoad method, so within class Embedder something like:

@PostLoad
private void initData() {
  if(notAutoInstantiated == null) {
    notAutoInstantiated = new NotAutoInstantiated();
  }
}

Update:

Warning! The upper code is working, but does have an unexpected side effect! As soon as you load your object with null pointer from the database, it is marked as dirty, because of this post load code! In my case, this side effects leads to an SQL update command from a thread, which should only load the data and hours of searching this bug!