Hibernate Tutorial
Core Hibernate
Hibernate Mapping
Hibernate Annotations
Hibernate with Spring Framework
Hibernate with Database
Hibernate Log4j
Inheritance 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:
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
.
@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.
@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.
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; }
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.
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.
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }