14
votes

I have tried omitting the @Embedded annotation and still the fields have been embedded in the table. I cannot find anything which would say that the @Embedded annotation is optional.

Is it or is it not optional?

The following code

@Embeddable
public class Address {
    String city;
    String street;
}

@Entity
public class Person {
    String name;
    @Embedded // it seems that it works even if this annotation is missing!?
    Address address;
}

generates always the same table

person
    name
    city
    street

even if I do not specify @Embedded.


My configuration:

  • JBoss EAP 6.4.0
  • hibernate-jpa-2.0-api-1.0.1.Final-redhat-3.jar

The JPA specification says:

http://docs.oracle.com/javaee/7/api/javax/persistence/Embedded.html

@javax.persistence.Embedded

Specifies a persistent field or property of an entity whose value is an instance of an embeddable class. The embeddable class must be annotated as Embeddable.

http://docs.oracle.com/javaee/7/api/javax/persistence/Embeddable.html

@javax.persistence.Embeddable

Specifies a class whose instances are stored as an intrinsic part of an owning entity and share the identity of the entity. Each of the persistent properties or fields of the embedded object is mapped to the database table for the entity.

2
You've found it by yourself already. There is not requirement for @Embedded in the specification. So i guess it is a descision of the implementation. It would be interesting to see if OpenJPA and EclipseLink do the same.Roman K
As kromit says, down to the vendor. The one I use (DataNucleus JPA) interprets Embeddable as 'instances of this class are always embedded'. The JDO spec on the other hand has explicit annotations/XML to allow a user to distinguish 'instances of this class are always embedded' and 'instances of this class are only embedded if the field is marked as such'.Neil Stockton
In general, the API tries to be as much convention over configuration as possible so many annotations or parameters of annotations are actually optional when there is a well-defined default for it. This is a prime example; if a class is embeddable, it is a pretty safe assumption that when it is used in an entity, it is to be treated as embedded. Push comes to shove the implementation could check the database meta data to see if that is actually the case or not.Gimby
@Gimby, why don't you post it as an answer?Honza Zidek
@HonzaZidek its a rather inconsequential risk don't you think? Even if you would decide to switch to a different persistence provider which is likely going to give you more problems than only this minor one, its a rather quick fix should it happen to be implemented differently (just add the annotation). In any case this existing question kind of backs up what I say: you only really need to specify these annotations when you want to be more specific. stackoverflow.com/questions/2578530/… .Gimby

2 Answers

3
votes

In case of using Hibernate it does not matter if you annotate the field itself (as @Embedded) or if you annotate the referenced class (as @Embeddable). At least one of both is needed to let Hibernate determine the type.

And there is a (implicit) statement about this inside the Hibernate documentation, take a look here: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/mapping.html#mapping-declaration-component

It says:

The Person entity has two component properties, homeAddress and bornIn. homeAddress property has not been annotated, but Hibernate will guess that it is a persistent component by looking for the @Embeddable annotation in the Address class.

-2
votes

Embedded-Embeddable is not mandatory, but it gives you nice OOP perspective of your entities' relationship. Another way to do such a thing - is to use OneToOne mapping. But in such a case entity WILL be written to separate table (while in case of embedded it CAN be written to the separate table in your DB).