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

allprog picture allprog · Nov 28, 2012 · Viewed 8.1k times · Source

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;      
}

Answer

Sylvain Lecoy picture Sylvain Lecoy · Nov 28, 2016

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à!