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à!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With