Fundamental question: Why aren't @Embedded objects always instantiated?
The interesting observation is that Ebean does not instantiate @Embedded objects if those do not contain basic datatypes (int, boolean...) or weren't touched before. Example:
@Entity
public class Embedder {
// getNotAutoInstantiated() will return null if this field was not touched before
@Embedded
private NotAutoInstantiated notAutoInstantiated = new NotAutoInstantiated();
// getAutoInstantiated() will always return an instance!
@Embedded
private AutoInstantiated autoInstantiated = new AutoInstantiated();
}
@Embeddable
public class AutoInstantiated {
// theKey is why this embedded object is always instantiated
private int theKey;
private String field1;
}
@Embeddable
public class NotAutoInstantiated {
private String field2;
}
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à!