Modelling Complex Relationships in Spring Boot Using @Embedded and @Embeddable
In Spring Boot, there are several types of entity relationships (mappings) that you can define to model the associations between entities. @Embedded and @Embeddable are one of such.
@Embeddable annotation is defined this way in the documentation:
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.
Here is a simple way to explain a class annotated with @Embeddable
Also to note: Embeddable types can be nested. That is, an @Embeddable class may have an attribute whose type is itself a different @Embeddable class.
@Embedded annotation is defined this way in the documentation:
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.
Let's see how it is written in code
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private Integer age;
@Embedded
private Address address;
}
The Employee entity has an Address field marked with @Embedded, and the Address class is written this way
@Embeddable
public class Address {
private String street;
private String city;
}
You may ask, why is this necessary?
This is a way to represent complex relationships in the database schema while maintaining a clear domain model in your application.
For example, the Address class could end up having 7 properties, and you may want to represent another property of type Contact - with fields like phone number, email etc.
If you keep adding more properties directly in your Employee class, things get bigger and could be confusing. So think of it as a way to make things cleaner and easy to be understood.
A class annotated with @Entity in Spring Boot can have more than one @Embeddable property. Each @Embeddable class represents an embedded object, and you can embed multiple such objects into an entity.
when we run the code, this will be the sql code that will be generated by JPA/Hibernate
CREATE TABLE employee (
id INT NOT NULL AUTO_INCREMENT,
city VARCHAR(255),
street VARCHAR(255),
age INT,
name VARCHAR(255),
PRIMARY KEY (id)
) ENGINE=InnoDB;
The image below is a screenshot of the table on MySQL workbench:
As you can see, there is only one table containing all the properties of Employee and Address class.
In summary, instead of having an @Entity class with a lot of fields, you can easily break similar fields into one class and use the @Embedded and @Embeddable annotation to map things so you still have one table.