Hibernate Tutorial

Core Hibernate

Hibernate Mapping

Hibernate Annotations

Hibernate with Spring Framework

Hibernate with Database

Hibernate Log4j

Inheritance Mapping

Hibernate - Component Mapping

In Hibernate, component mapping, often referred to as "component" or "embedded" objects, allows you to map a non-entity class as a component of an entity. This approach is useful when you have a group of fields that can be logically grouped but don't warrant their own separate entity and table. These are value types that do not have their own lifecycle or identity.

Let's look at an example to understand this:

Example: Mapping an Address as a Component of a User

Let's say you have a User entity and you want to associate an Address with it. However, the Address doesn't make sense on its own without a User, so you decide to make it an embedded component of User.

  • Define the Address component class
@Embeddable
public class Address {

    private String street;
    private String city;
    private String state;
    private String zipcode;

    // constructors, getters, setters
}

Note the use of @Embeddable annotation. This marks the class as a value type, so Hibernate knows it can be embedded in an entity.

  • Embed the Address in the User entity
@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @Embedded
    private Address address;

    // constructors, getters, setters
}

Here, @Embedded tells Hibernate that address is an embedded component.

  • Overriding Column Names (optional)

If you want the columns in the database table to have different names than the fields in the Address class, you can use the @AttributeOverrides and @AttributeOverride annotations.

@Entity
public class User {

    // ... other fields ...

    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name="street", column=@Column(name="address_street")),
        @AttributeOverride(name="city", column=@Column(name="address_city")),
        // similarly for state and zipcode
    })
    private Address address;
}
  • Using the Component

Now, when you persist a User, the Address details will be stored in the same table as the User:

Session session = sessionFactory.openSession();
session.beginTransaction();

User user = new User();
user.setName("John Doe");

Address address = new Address("123 Elm St", "Springfield", "IL", "12345");
user.setAddress(address);

session.save(user);
session.getTransaction().commit();
session.close();

This will create a single record in the User table with columns for all the User and Address fields.

Benefits of Component Mapping:

  • Reusable Components: The @Embeddable classes can be reused across different entities.

  • Logical Grouping: Allows you to keep related fields together in a value type, providing a clearer and more modular design.

  • No Separate Lifecycle: Since the component doesn't have its own lifecycle, you don't have to manage it separately. Any changes to the component are automatically reflected when the parent entity is persisted.

However, always remember that component mapping is best suited for closely related fields that logically belong together and don't warrant their own separate lifecycle or table. If a component grows too complex or starts to feel like it could exist independently, it might be better to consider it as a separate entity.

  1. Hibernate component mapping example:

    Mapping components in Hibernate involves creating reusable components and embedding them within entities.

    @Entity
    @Table(name = "employees")
    public class Employee {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "employee_id")
        private Long id;
    
        @Embedded
        private Address address;
    
        // Other properties and methods
    }
    
    @Embeddable
    public class Address {
        @Column(name = "street")
        private String street;
    
        @Column(name = "city")
        private String city;
    
        @Column(name = "zipcode")
        private String zipcode;
    
        // Getters and setters
    }
    
  2. Mapping components in Hibernate entities:

    Map components in Hibernate entities using @Embedded annotation.

    @Entity
    @Table(name = "employees")
    public class Employee {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "employee_id")
        private Long id;
    
        @Embedded
        private Address address;
    
        // Other properties and methods
    }
    
    @Embeddable
    public class Address {
        @Column(name = "street")
        private String street;
    
        @Column(name = "city")
        private String city;
    
        @Column(name = "zipcode")
        private String zipcode;
    
        // Getters and setters
    }
    
  3. Composite keys and component mapping in Hibernate:

    Use components for composite keys in Hibernate entities.

    @Entity
    @Table(name = "employees")
    public class Employee {
        @EmbeddedId
        private EmployeeId employeeId;
    
        @Embedded
        private Address address;
    
        // Other properties and methods
    }
    
    @Embeddable
    public class EmployeeId implements Serializable {
        @Column(name = "employee_id")
        private Long id;
    
        @Column(name = "company_id")
        private Long companyId;
    
        // Getters and setters
    }
    
  4. Hibernate embedded component mapping:

    Embed components directly within entities using @Embeddable.

    @Entity
    @Table(name = "employees")
    public class Employee {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "employee_id")
        private Long id;
    
        @Embedded
        private ContactInfo contactInfo;
    
        // Other properties and methods
    }
    
    @Embeddable
    public class ContactInfo {
        @Column(name = "email")
        private String email;
    
        @Column(name = "phone")
        private String phone;
    
        // Getters and setters
    }
    
  5. Component mapping annotations in Hibernate:

    Use annotations like @Embeddable, @Embedded, @Embeddable, and others for component mapping.

    @Entity
    @Table(name = "employees")
    public class Employee {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "employee_id")
        private Long id;
    
        @Embedded
        private ContactInfo contactInfo;
    
        // Other properties and methods
    }
    
    @Embeddable
    public class ContactInfo {
        @Column(name = "email")
        private String email;
    
        @Column(name = "phone")
        private String phone;
    
        // Getters and setters
    }
    
  6. Reuse of components in Hibernate mapping:

    Reuse components in multiple entities to promote code reusability.

    @Entity
    @Table(name = "employees")
    public class Employee {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "employee_id")
        private Long id;
    
        @Embedded
        private ContactInfo contactInfo;
    
        // Other properties and methods
    }
    
    @Entity
    @Table(name = "customers")
    public class Customer {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "customer_id")
        private Long id;
    
        @Embedded
        private ContactInfo contactInfo;
    
        // Other properties and methods
    }
    
    @Embeddable
    public class ContactInfo {
        @Column(name = "email")
        private String email;
    
        @Column(name = "phone")
        private String phone;
    
        // Getters and setters
    }
    
  7. Cascading operations with component mapping in Hibernate:

    Define cascading operations for components to propagate changes.

    @Entity
    @Table(name = "employees")
    public class Employee {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "employee_id")
        private Long id;
    
        @Embedded
        @Cascade(value = { CascadeType.ALL }) // Cascading operations
        private ContactInfo contactInfo;
    
        // Other properties and methods
    }
    
    @Embeddable
    public class ContactInfo {
        @Column(name = "email")
        private String email;
    
        @Column(name = "phone")
        private String phone;
    
        // Getters and setters
    }
    
  8. Handling associations with component mapping in Hibernate:

    Components can be associated with other entities or components.

    @Entity
    @Table(name = "employees")
    public class Employee {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "employee_id")
        private Long id;
    
        @Embedded
        private ContactInfo contactInfo;
    
        @ManyToOne
        @JoinColumn(name = "department_id")
        private Department department;
    
        // Other properties and methods
    }
    
    @Entity
    @Table(name = "departments")
    public class Department {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "department_id")
        private Long id;
    
        // Other properties and methods
    }
    
    @Embeddable
    public class ContactInfo {
        @Column(name = "email")
        private String email;
    
        @Column(name = "phone")
        private String phone;
    
        // Getters and setters
    }
    
  9. Mapping value types as components in Hibernate:

    Map value types as components using @Embeddable.

    @Entity
    @Table(name = "employees")
    public class Employee {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "employee_id")
        private Long id;
    
        @Embedded
        private Salary salary; // Value type as component
    
        // Other properties and methods
    }
    
    @Embeddable
    public class Salary {
        @Column(name = "amount")
        private BigDecimal amount;
    
        @Column(name = "currency")
        private String currency;
    
        // Getters and setters
    }