An @Embedded object is not automatically created if it does not have basic data type fields

Fundamental question: why are @Embedded objects always created?

An interesting point is that Ebean does not create instances of @Embedded unless they contain basic data types (int, boolean ...) or have not previously been affected. 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; } 
+8
java jpa ebean
source share
3 answers

I don’t think the JPA specification clearly describes what should happen when the properties of the @Embedded object @Embedded all null, but at least some implementations treat the object with null properties as a null object, which is what you see.

This seems like a reasonable implementation. Of course, this was useful in my code (using Hibernate), where if I set the @Embedded object to null, I want it to stay empty when I load the saved version.

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

+3
source share

You might want to check:

https://hibernate.atlassian.net/browse/HHH-7610

In particular, since 5.1:

 static final String CREATE_EMPTY_COMPOSITES_ENABLED Enable instantiation of composite/embedded objects when all of its attribute values are null. The default (and historical) behavior is that a null reference will be used to represent the composite when all of its attributes are null @since 5.1 @see Constant Field Values 

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

+3
source share

I just got the same problem with Hibernate. The answer to the original question is why.

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

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

Update:

A warning! The top code works, but has an unexpected side effect! As soon as you load your null pointer object from the database, it will be marked as dirty due to this mail loading code! In my case, these side effects lead to the SQL update command from the stream, which should only load data and hours of searching for this error!

+1
source share

All Articles