Mapping Basics
Mapping Basics Interview with follow-up questions
1. What is Hibernate Mapping and why is it important?
Hibernate Mapping is the process of defining how Java entity classes correspond to database tables, and how their fields map to columns. It is foundational to Hibernate's ORM functionality: without accurate mappings, Hibernate cannot generate correct SQL or maintain object state.
Why it is important:
- Eliminates hand-written SQL for CRUD — Once mapping is defined, Hibernate generates
INSERT,SELECT,UPDATE, andDELETEstatements automatically. - Object-relational impedance mismatch — Relational databases think in tables and rows; Java thinks in objects and references. Mapping bridges this gap (inheritance hierarchies, collections, embedded types).
- Database portability — Mappings are database-agnostic. Switching from MySQL to PostgreSQL requires only a dialect change, not query rewrites.
- Type safety — Working with Java types rather than raw SQL strings catches many errors at compile time.
Two ways to define mappings in Hibernate 6:
1. Annotation-based (standard, preferred):
import jakarta.persistence.*;
@Entity
@Table(name = "product")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "product_name", nullable = false, length = 200)
private String name;
@Column(precision = 10, scale = 2)
private BigDecimal price;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "category_id")
private Category category;
// getters and setters
}
2. XML mapping files (.hbm.xml): Legacy approach, still supported but rarely used in new projects.
Key mapping annotations (all from jakarta.persistence):
@Entity,@Table— class-to-table@Id,@GeneratedValue— primary key@Column— field-to-column customisation@OneToOne,@OneToMany,@ManyToOne,@ManyToMany— relationships@Embedded,@Embeddable— value types@Inheritance— hierarchy mapping strategies
Follow-up 1
Can you explain the different types of Hibernate Mapping?
Yes, there are three types of Hibernate Mapping:
XML Mapping: In this approach, the mapping between Java objects and database tables is defined using XML configuration files.
Annotation Mapping: In this approach, the mapping is defined using Java annotations directly in the entity classes.
Java Mapping: In this approach, the mapping is defined programmatically using Java code.
Each type of mapping has its own advantages and can be used based on the project requirements and developer preferences.
Follow-up 2
What is the role of the mapping file in Hibernate?
The mapping file in Hibernate is used to define the mapping between Java objects and database tables. It specifies how the properties of a Java class are mapped to the columns of a database table. The mapping file contains information about the table name, column names, data types, relationships, and other mapping details. Hibernate uses this mapping file to generate the necessary SQL queries for performing database operations.
Follow-up 3
How does Hibernate handle mapping for inherited classes?
Hibernate provides different strategies for mapping inherited classes:
Single Table Inheritance: In this strategy, all the properties of the inherited classes are stored in a single table. Hibernate uses a discriminator column to differentiate between different types of objects.
Table Per Class Inheritance: In this strategy, each class in the inheritance hierarchy is mapped to a separate table. The properties of each class are stored in their respective tables.
Joined Table Inheritance: In this strategy, each class in the inheritance hierarchy is mapped to a separate table, but the tables are linked through foreign key relationships. The properties of each class are stored in their respective tables.
The choice of inheritance mapping strategy depends on the specific requirements of the application and the database design.
2. How does Hibernate perform Class to Table Mapping?
Hibernate maps a Java class to a database table through annotations placed directly on the class and its fields. The mapping instructs Hibernate which table to query, which column each field corresponds to, and how to generate/manage primary keys.
Minimal annotation-based mapping:
import jakarta.persistence.*;
@Entity // marks this class as a managed entity
@Table(name = "customer") // maps to the "customer" table (optional if name matches)
public class Customer {
@Id // marks the primary key field
@GeneratedValue(strategy = GenerationType.IDENTITY) // auto-increment
private Long id;
@Column(name = "full_name", nullable = false, length = 150)
private String name;
@Column(unique = true, nullable = false)
private String email;
@Column(name = "created_at")
private LocalDateTime createdAt;
}
@GeneratedValue strategies:
| Strategy | Behaviour |
|---|---|
IDENTITY |
DB auto-increment (SERIAL, AUTO_INCREMENT) |
SEQUENCE |
DB sequence object (default in Hibernate 6 for numerics) |
TABLE |
Portable but slow; simulated sequence in a table |
AUTO |
Hibernate picks the best strategy for the dialect |
UUID |
UUID primary key (supported natively in Hibernate 6) |
Field-level conventions:
- If
@Columnis omitted, the column name defaults to the field name (or snake_case with Spring Boot'sspring.jpa.hibernate.naming.physical-strategy). - If
@Tableis omitted, the table name defaults to the class name. - Fields annotated
@Transientare not persisted.
XML alternative (legacy): Older projects used .hbm.xml files (``). Modern projects use annotations exclusively; XML support remains but is discouraged in new code.
Hibernate 6 note: The @Entity annotation must come from jakarta.persistence (not javax.persistence). Using javax.persistence with Spring Boot 3 / Hibernate 6 causes ClassNotFoundException at startup.
Follow-up 1
What are the key elements in a mapping file for Class to Table Mapping?
The key elements in a mapping file for Class to Table Mapping in Hibernate are:
`` element: It defines the Java class to be mapped to a database table.
`` element: It defines the primary key property of the Java class.
`` element: It defines the properties of the Java class that are mapped to columns in the database table.
`` element: It defines a many-to-one relationship between two Java classes.
`` element: It defines a one-to-many relationship between two Java classes.
`` element: It defines a many-to-many relationship between two Java classes.
Follow-up 2
Can you give an example of Class to Table Mapping in Hibernate?
Sure! Here's an example of Class to Table Mapping in Hibernate using XML mapping file:
In this example, the Java class com.example.User is mapped to the database table users. The id property of the User class is mapped to the user_id column in the table. The username and password properties are mapped to the username and password columns respectively. The role property is a many-to-one relationship with the com.example.Role class, and it is mapped to the role_id column in the table.
Follow-up 3
What happens if the mapping between a class and a table is not correctly defined?
If the mapping between a class and a table is not correctly defined in Hibernate, it can lead to various issues such as:
Incorrect SQL statements being generated: Hibernate uses the mapping information to generate SQL statements for CRUD operations. If the mapping is incorrect, the generated SQL statements may not work as expected.
Data inconsistency: If the mapping is incorrect, it can lead to data being stored or retrieved incorrectly from the database.
Runtime exceptions: Hibernate may throw runtime exceptions if the mapping is not correctly defined, such as
MappingExceptionorHibernateException.
It is important to ensure that the mapping between a class and a table is correctly defined to avoid these issues.
3. What is Inheritance Mapping in Hibernate?
Inheritance Mapping in Hibernate allows you to persist a Java class hierarchy — a superclass and its subclasses — into a relational database, which has no native concept of inheritance. Hibernate provides three strategies, each a different trade-off between normalisation and performance.
1. SINGLE_TABLE (default)
All classes in the hierarchy share one table. A discriminator column identifies which subclass a row represents.
import jakarta.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "vehicle_type")
public abstract class Vehicle {
@Id @GeneratedValue private Long id;
private String manufacturer;
}
@Entity
@DiscriminatorValue("CAR")
public class Car extends Vehicle {
private int numDoors;
}
@Entity
@DiscriminatorValue("TRUCK")
public class Truck extends Vehicle {
private double payloadTons;
}
- Pros: Best query performance (single
SELECT); no joins. - Cons: Subclass-specific columns are nullable; table grows wide with many subclasses.
2. JOINED
Each class has its own table. The subclass table contains only its own columns plus a foreign key to the parent table.
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Vehicle { ... }
@Entity
@PrimaryKeyJoinColumn(name = "car_id")
public class Car extends Vehicle { private int numDoors; }
- Pros: Fully normalised; no nullable columns.
- Cons: Requires
JOINfor every query on a subclass; more SQL overhead.
3. TABLE_PER_CLASS
Each concrete class has a standalone table containing all inherited columns too.
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Vehicle { ... }
- Pros: No joins for single-type queries.
- Cons: Polymorphic queries (e.g.,
SELECT v FROM Vehicle v) requireUNION ALL; no shared sequence for IDs (must useTABLEorUUIDstrategy).
Interview follow-up: SINGLE_TABLE is the default and usually the best performer. Use JOINED when strict normalisation and data integrity matter. Avoid TABLE_PER_CLASS unless polymorphic queries are rare.
Follow-up 1
Can you explain the different strategies for Inheritance Mapping in Hibernate?
There are three strategies for Inheritance Mapping in Hibernate:
Single Table Strategy: In this strategy, all the classes in the inheritance hierarchy are mapped to a single database table. The table contains columns for all the attributes of all the classes, with some columns being nullable for the attributes that are not applicable to certain classes.
Table Per Class Strategy: In this strategy, each class in the inheritance hierarchy is mapped to a separate database table. The tables contain columns for the attributes of the respective classes.
Joined Table Strategy: In this strategy, each class in the inheritance hierarchy is mapped to a separate database table, but the tables are linked through foreign key relationships. The common attributes are stored in a shared table, and each class table contains only the specific attributes for that class.
Follow-up 2
What are the advantages and disadvantages of each Inheritance Mapping strategy?
The advantages and disadvantages of each Inheritance Mapping strategy are as follows:
Single Table Strategy:
- Advantages: Simple and efficient, no joins required for querying the data.
- Disadvantages: Redundant columns for attributes that are not applicable to certain classes, can lead to a large table with many nullable columns.
Table Per Class Strategy:
- Advantages: No redundant columns, each table represents a specific class.
- Disadvantages: Requires joins for querying data across multiple classes, can lead to more complex queries.
Joined Table Strategy:
- Advantages: No redundant columns, each table represents a specific class, allows for efficient querying of specific class data.
- Disadvantages: Requires joins for querying data across multiple classes, can lead to more complex queries, additional overhead of maintaining foreign key relationships.
Follow-up 3
Can you give an example of Inheritance Mapping in Hibernate?
Sure! Here's an example of Inheritance Mapping in Hibernate using the Single Table Strategy:
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "employee_type", discriminatorType = DiscriminatorType.STRING)
public abstract class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// common attributes and methods
}
@Entity
@DiscriminatorValue("manager")
public class Manager extends Employee {
private String department;
// additional attributes and methods for Manager
}
@Entity
@DiscriminatorValue("developer")
public class Developer extends Employee {
private String programmingLanguage;
// additional attributes and methods for Developer
}
4. What are Associations in Hibernate Mapping?
Associations in Hibernate mapping define relationships between entity classes and instruct Hibernate how to join the corresponding database tables. All association annotations come from jakarta.persistence.
Four association types:
1. @ManyToOne (most common)
import jakarta.persistence.*;
@Entity
public class Order {
@Id @GeneratedValue private Long id;
@ManyToOne(fetch = FetchType.LAZY) // always use LAZY for @ManyToOne
@JoinColumn(name = "customer_id")
private Customer customer;
}
2. @OneToMany (bidirectional with @ManyToOne)
@Entity
public class Customer {
@Id @GeneratedValue private Long id;
@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, orphanRemoval = true)
private List orders = new ArrayList<>();
}
mappedBy points to the field name in Order that owns the foreign key. The Customer side does not own the join column.
3. @OneToOne
@Entity
public class User {
@Id @GeneratedValue private Long id;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "profile_id", unique = true)
private UserProfile profile;
}
4. @ManyToMany
@Entity
public class Student {
@Id @GeneratedValue private Long id;
@ManyToMany
@JoinTable(
name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id")
)
private Set courses = new HashSet<>();
}
Key concepts:
- Owning side vs. inverse side — The side with
@JoinColumnor@JoinTableowns the relationship.mappedBymarks the inverse side. Only the owning side updates the foreign key column. - Cascade types —
CascadeType.ALL,PERSIST,MERGE,REMOVE,REFRESH,DETACHcontrol which operations propagate from parent to child. orphanRemoval = true— Automatically deletes child entities removed from the parent collection.fetch = FetchType.LAZY— Default for@OneToManyand@ManyToMany; should also be set explicitly for@ManyToOneand@OneToOne.
Follow-up 1
What is the difference between One-to-One, One-to-Many, and Many-to-Many associations?
In Hibernate, the difference between One-to-One, One-to-Many, and Many-to-Many associations is as follows:
One-to-One: This association represents a relationship where one entity is associated with exactly one instance of another entity.
One-to-Many: This association represents a relationship where one entity is associated with multiple instances of another entity.
Many-to-Many: This association represents a relationship where multiple instances of one entity are associated with multiple instances of another entity.
Follow-up 2
How does Hibernate handle bidirectional associations?
Hibernate handles bidirectional associations by maintaining the associations from both sides of the relationship. This means that each entity in the association has a reference to the other entity. Hibernate uses this bidirectional association to automatically synchronize the changes made on one side of the association to the other side.
Follow-up 3
Can you give an example of an association mapping in Hibernate?
Sure! Here's an example of a One-to-Many association mapping in Hibernate:
@Entity
public class Department {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "department")
private List employees;
// getters and setters
}
@Entity
public class Employee {
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToOne
private Department department;
// getters and setters
}
In this example, the Department entity has a one-to-many association with the Employee entity. The Department entity has a list of Employee objects, and each Employee object has a reference to the Department it belongs to.
5. How does Hibernate handle Composite Primary Keys?
A composite primary key uses two or more columns together to uniquely identify a row. Hibernate provides two approaches: @EmbeddedId and @IdClass.
Approach 1: @EmbeddedId (preferred)
Create a separate class annotated @Embeddable to represent the composite key:
import jakarta.persistence.*;
import java.io.Serializable;
import java.util.Objects;
@Embeddable
public class OrderLineId implements Serializable {
private Long orderId;
private Long productId;
// required: no-arg constructor, equals(), hashCode()
public OrderLineId() {}
public OrderLineId(Long orderId, Long productId) {
this.orderId = orderId;
this.productId = productId;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof OrderLineId that)) return false;
return Objects.equals(orderId, that.orderId) &&
Objects.equals(productId, that.productId);
}
@Override
public int hashCode() { return Objects.hash(orderId, productId); }
}
@Entity
public class OrderLine {
@EmbeddedId
private OrderLineId id;
private int quantity;
private BigDecimal unitPrice;
}
Approach 2: @IdClass
Keep the fields on the entity and reference a separate ID class:
@IdClass(OrderLineId.class)
@Entity
public class OrderLine {
@Id private Long orderId;
@Id private Long productId;
private int quantity;
}
OrderLineId here is a plain class with matching field names (no @Embeddable required), but must still implement Serializable and override equals/hashCode.
Using composite keys:
OrderLineId key = new OrderLineId(1L, 42L);
OrderLine line = em.find(OrderLine.class, key);
Rules for the ID class (both approaches):
- Must implement
Serializable - Must override
equals()andhashCode()— failure here causes incorrect caching and incorrect identity comparison - Must have a public no-argument constructor
When to prefer @EmbeddedId: When the composite key is a meaningful value object (e.g., OrderLineId) that you reference in queries. @IdClass is simpler but less object-oriented.
Follow-up 1
What is a Composite Primary Key?
A composite primary key is a primary key that consists of multiple columns. It is used to uniquely identify a record in a database table. Instead of using a single column as the primary key, a composite primary key uses a combination of two or more columns.
Follow-up 2
Can you give an example of mapping a Composite Primary Key in Hibernate?
Sure! Here's an example of mapping a composite primary key in Hibernate:
@Embeddable
public class OrderId implements Serializable {
@Column(name = "order_number")
private String orderNumber;
@Column(name = "customer_id")
private int customerId;
// getters and setters
}
@Entity
@Table(name = "orders")
public class Order {
@EmbeddedId
private OrderId id;
// other properties
// getters and setters
}
Follow-up 3
What are the potential issues when using Composite Primary Keys in Hibernate?
When using composite primary keys in Hibernate, there are a few potential issues to consider:
Complexity: Mapping composite primary keys can be more complex compared to using a single-column primary key.
Performance: Composite primary keys can have an impact on performance, especially when querying or joining tables based on the composite key.
Maintenance: If the structure of the composite primary key changes, it can require updates to the entity class and database schema.
Portability: Composite primary keys may not be supported by all databases, so there could be portability issues if you need to switch databases.
Live mock interview
Mock interview: Mapping Basics
- Read your scene and goals
- Talk it out; goals tick off live
- Get a score and stronger lines
Your voice and your AI key never touch our servers; the key stays in this browser and is sent only to Google. Only your round scores are saved to track progress.