Hibernate & JPA Interview Question – MNCs Choice

Support this post with a reaction:

Hibernate Interview Questions

1. What is Hibernate, and how does it differ from JDBC? What are its advantages?

Hibernate is an Object-Relational Mapping (ORM) framework for Java. It helps developers map Java classes to database tables and Java data types to SQL data types, allowing you to interact with databases using standard Java objects rather than SQL queries.

Difference between Hibernate and JDBC

AspectJDBCHibernate
Query TypeSQL (manual)HQL (object-oriented)
MappingManual mappingAutomatic ORM mapping
CodeMore boilerplateLess, cleaner code
Database DependencyDB-specific SQLDB-independent via dialects
CachingNot availableBuilt-in caching support
Transaction HandlingManualAutomatic/integrated
MaintenanceHarderEasier

Advantages of Hibernate (Short)

  • Reduces boilerplate code
  • Automatic object-table mapping
  • Database independent (HQL)
  • Built-in caching for better performance
  • Handles transactions automatically
  • Supports lazy loading and relationships
  • Easier to maintain and scale

2. What is Object-Relational Mapping (ORM), and how does Hibernate implement it?

Object-Relational Mapping (ORM) is a technique that maps Java objects to database tables and vice versa. It allows developers to interact with the database using Java objects instead of SQL queries.

How does Hibernate implement ORM?

Hibernate uses:

  • Annotations (like @Entity, @Table, @Id, @Column) or XML files to define the mapping between Java classes and database tables.
  • Session objects to manage CRUD operations.
  • HQL (Hibernate Query Language) to perform database operations using object-oriented syntax.
  • Automatic handling of relationships (OneToMany, ManyToOne, etc.), inheritance, and cascading.

3. Describe the architecture of Hibernate. What are the roles of Configuration, SessionFactory, Session, Transaction, and Cache?

Hibernate follows a layered architecture that abstracts interactions between Java applications and databases. It includes various components to handle configuration, session management, transactions, and caching.

Key Components and Their Roles

1. Configuration

  • Role: Loads Hibernate configuration details (like DB connection settings and mapping files).
  • Use: Usually configured via hibernate.cfg.xml or Java-based configuration.
  • Creates: SessionFactory.

2. SessionFactory

  • Role: A thread-safe, heavy-weight object used to create Session objects.
  • Lifecycle: Created once per application; reused across sessions.
  • Contains: Metadata and connection pool.

3. Session

  • Role: Main interface for performing CRUD operations on persistent objects.
  • Not Thread-safe: Should be used for a single unit of work.
  • Handles: Object-level caching (first-level cache).

4. Transaction

  • Role: Manages atomicity and consistency during database operations.
  • Use: Ensures commit or rollback of changes as a single unit of work.

5. Cache

  • First-Level Cache: Enabled by default at the Session level.
  • Second-Level Cache: Optional, configured separately; shared across sessions to reduce DB hits.
  • Query Cache: Optional cache to store query results.

Flow of Hibernate Architecture

  1. Configuration loads DB and mapping settings.
  2. SessionFactory is created from Configuration.
  3. Session is opened from SessionFactory.
  4. Transaction is started via Session.
  5. Perform CRUD operations.
  6. Commit or rollback Transaction.
  7. Close the Session.

4. Explain the life cycle of a Hibernate entity. What is the difference between Transient, Persistent, and Detached states?

An entity in Hibernate goes through three main states during its life cycle:

1. Transient State

  • Meaning: The object is created using new, but not associated with any Hibernate Session.
  • Not saved to the database.
  • No primary key (ID is not generated).
  • Example:
Student s = new Student(); // Transient state

2. Persistent State

  • Meaning: The object is associated with an active Session and will be tracked by Hibernate.
  • Any changes to the object will be automatically synchronized with the database during flush/commit.
  • Example:
session.save(s); // Now in Persistent state

3. Detached State

  • Meaning: The object was once persistent (attached to a session), but now the session is closed.
  • It is not being tracked by Hibernate anymore.
  • You can reattach it using session.update() or session.merge().
  • Example:
session.close(); // s becomes Detached

State Comparison Table

StateAssociated with Session?Stored in DB?Changes tracked?
Transient❌ No❌ No❌ No
Persistentβœ… Yesβœ… Yesβœ… Yes
Detached❌ Noβœ… Yes❌ No

5. What are the differences between Session and SessionFactory? Are they thread-safe?

In Hibernate, SessionFactory is a heavyweight, thread-safe object that is used to create Session instances. It is created once during the application startup and is meant to be reused throughout the application’s lifetime. SessionFactory is responsible for reading the Hibernate configuration (like database connection details and entity mappings) and holds the metadata of persistent classes. It also optionally manages the second-level cache to optimize performance.

In contrast, a Session is a lightweight, non-thread-safe object that represents a single unit of work with the database. It is created by the SessionFactory and is used to perform CRUD operations like saving, updating, deleting, or retrieving Java objects from the database. Each session has its own first-level cache, which helps reduce database hits within the scope of that session.

The key difference lies in their usage and lifecycle. While SessionFactory is shared globally and reused across threads, a Session is short-lived and should be used per request or transaction. You should never share a Session between multiple threads as it may lead to concurrency issues.

6. What is the difference between get() and load() methods in Hibernate?

Hibernate provides two methods to fetch data from the database: get() and load(). Both are used to retrieve an entity by its primary key, but they behave differently.

1. get() Method:

  • Immediate Fetching: Hits the database immediately and returns the actual object.
  • Returns: null if the object is not found.
  • Use Case: When you are unsure whether the object exists and want to check.

Example:

Student s = session.get(Student.class, 1);

2. load() Method:

  • Lazy Loading: Returns a proxy object without hitting the database immediately.
  • Throws Exception: If the object doesn’t exist, it throws ObjectNotFoundException when accessed.
  • Use Case: When you are sure the object exists and want to improve performance using lazy fetch.

Example:

Student s = session.load(Student.class, 1);
Featureget()load()
Fetching TypeEager (immediate)Lazy (proxy)
Return if MissingReturns nullThrows ObjectNotFoundException
Proxy ObjectNoYes
When to UseWhen object may not existWhen you’re sure object exists

7. Compare save(), persist(), and saveOrUpdate() in terms of behavior and entity state management.

save()

The save() method is used to store a new object (like a student or employee) into the database. It returns the generated ID of that object. It can also save an object even if it was saved before in another session (detached state).

Example:

Student student = new Student();
student.setName("Rahul");

Serializable id = session.save(student); // saves the student and returns the ID
System.out.println("Saved with ID: " + id);
  • Works with new and detached objects
  • Returns the ID (e.g., 101)
  • Saves immediately or on flush
  • Does not need cascade settings

persist()

The persist() method is almost like save(), but it does not return the ID. It follows JPA standards and does not work with detached objects. You must use it only for new objects. Also, it will save the data only when the session is flushed or the transaction is committed.

Example:

Student student = new Student();
student.setName("Rahul");

session.persist(student); // saves the student but returns nothing
  • Works only with new objects
  • Doesn’t return ID
  • Inserts during flush/commit
  • Needs CascadeType.PERSIST to save child objects

saveOrUpdate()

The saveOrUpdate() method is smart. It checks whether the object is new or already exists. If it’s new, it will insert it. If it already exists in the database (has an ID), it will update it. It works for both new and detached objects.

Example:

Student student = new Student();
student.setId(101); // already exists
student.setName("Updated Name");

session.saveOrUpdate(student); // will update if exists, save if not
  • Works with both new and old objects
  • No ID return
  • Automatically decides insert or update
  • Useful when you’re not sure if the object is new or existing

8. How is transaction management handled in Hibernate using Session.beginTransaction(), commit(), and rollback()?

In Hibernate, a transaction ensures that a set of database operations are executed in a safe, consistent, and atomic way β€” meaning either all operations succeed, or none do. This helps prevent issues like partial updates or data corruption. Hibernate handles transactions using the Transaction API along with the Session object.

Key Methods:

  1. beginTransaction()
    • Starts a new database transaction.
    • Called on the Session object.
  2. commit()
    • Finalizes the transaction.
    • Applies all changes made during the transaction to the database.
  3. rollback()
    • Cancels the transaction.
    • Reverts all changes if any error occurs.

Example

Session session = sessionFactory.openSession();
Transaction tx = null;

try {
    tx = session.beginTransaction();

    Student s = new Student();
    s.setName("Rahul");
    session.save(s); // Save operation inside the transaction

    tx.commit(); // Commit if everything is successful
} catch (Exception e) {
    if (tx != null) tx.rollback(); // Rollback on error
    e.printStackTrace();
} finally {
    session.close();
}

What Happens in the Above Code?

  • A new session is opened.
  • A transaction is started using beginTransaction().
  • The student object is saved.
  • If all goes well, commit() saves changes to the database.
  • If something fails (like an exception), rollback() undoes all changes.
  • The session is closed at the end.

9. What is the difference between HQL (Hibernate Query Language) and SQL? What are the advantages of using HQL?

AspectSQL (Structured Query Language)HQL (Hibernate Query Language)
Works OnTables and columns directlyJava classes and their properties (objects)
Return TypeReturns rows and columns (ResultSet)Returns Java objects/entities
Database Dependent?Yes (DB-specific syntax may vary)No (DB-independent; Hibernate converts to SQL)
Query StyleTable-orientedObject-oriented
JoinsManual joins using table namesUses object relationships (like mapped associations)
Use in HibernateCan be used but not recommendedPreferred in Hibernate for object manipulation

Advantages of HQL (Hibernate Query Language)

  • Object-Oriented: Uses Java class and property names instead of table/column names.
  • Database Independent: Works across different databases using Hibernate dialects.
  • Returns Objects: Fetches Java entities instead of raw data.
  • Supports Relationships: Easily queries mapped associations like OneToMany.
  • Cleaner Code: Reduces SQL errors and aligns better with Java code.

10. How does the Criteria API differ from HQL? When would you use each for dynamic queries?

HQL (Hibernate Query Language) is a string-based, object-oriented query language that looks similar to SQL but works with Java class names and fields instead of table and column names. It’s very useful when your queries are staticβ€”meaning the structure doesn’t change at runtime. For example, if you want to get all students named “Rahul”, you can simply write:

String hql = "FROM Student WHERE name = :name";
Query query = session.createQuery(hql);
query.setParameter("name", "Rahul");
List<Student> list = query.list();

This is clean, readable, and easy to maintain if the query is fixed.

Criteria API is useful when you need to build dynamic queries. Instead of using strings, you use Java methods to build the query step by step. This is especially helpful when the query changes based on user inputβ€”like applying different filters based on a search form. For example:

CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<Student> cq = cb.createQuery(Student.class);
Root<Student> root = cq.from(Student.class);

List<Predicate> predicates = new ArrayList<>();
if (nameFilter != null) {
    predicates.add(cb.equal(root.get("name"), nameFilter));
}
if (ageFilter != null) {
    predicates.add(cb.equal(root.get("age"), ageFilter));
}
cq.select(root).where(cb.and(predicates.toArray(new Predicate[0])));

List<Student> result = session.createQuery(cq).getResultList();

Here, you can easily add or remove conditions without rewriting the whole query, making it perfect for advanced search, admin dashboards, or filter panels.

In summary, use HQL for simple, fixed queries and use the Criteria API when you need flexible, dynamic queries that change at runtime.

11. What is Hibernate caching? What is the difference between first-level and second-level caching?

Hibernate caching is a performance optimization technique that reduces the number of database queries by storing frequently accessed data in memory. Instead of hitting the database every time you fetch an entity, Hibernate can return data from its internal cache if it was previously loaded.

Caching helps improve speed, reduce database load, and make applications more efficient.

Types of Caching in Hibernate

1. First-Level Cache (Session Cache)

  • Enabled by default
  • Works at the Session level
  • Data is cached per session (only available within the same session)
  • When you fetch the same entity twice in the same session, the second fetch is served from memory
Session session = sessionFactory.openSession();
Student s1 = session.get(Student.class, 1); // Hits DB
Student s2 = session.get(Student.class, 1); // Comes from cache

2. Second-Level Cache

  • Optional – must be enabled and configured explicitly
  • Works at the SessionFactory level
  • Shared across multiple sessions
  • Useful for caching data that doesn’t change often and is accessed frequently
// First time (from DB, stored in second-level cache)
Session s1 = sessionFactory.openSession();
Student student = s1.get(Student.class, 1);
s1.close();

// Second time (new session, from cache if enabled)
Session s2 = sessionFactory.openSession();
Student sameStudent = s2.get(Student.class, 1);
s2.close();

12. What are the benefits of using second-level cache, and how do you enable it?

Benefits of Using Second-Level Cache in Hibernate

  1. Improves Performance
    • Reduces repeated database queries for frequently accessed data.
  2. Shared Across Sessions
    • Unlike first-level cache, second-level cache is shared across multiple sessions and users.
  3. Reduces Database Load
    • Less traffic to the database means better scalability and responsiveness.
  4. Faster Access to Read-Only or Rarely Changing Data
    • Ideal for caching reference or lookup data like categories, states, roles, etc.
  5. Customizable
    • You can choose what entities or collections to cache and for how long.

How to Enable Second-Level Cache in Hibernate

1. Add a Cache Provider Dependency (e.g., EHCache, Infinispan) For EHCache, add to pom.xml:

<dependency>
    <groupId>org.hibernate.orm</groupId>
    <artifactId>hibernate-ehcache</artifactId>
    <version>YOUR_HIBERNATE_VERSION</version>
</dependency>

2. Update hibernate.cfg.xml or application.properties:

<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.region.factory_class">
    org.hibernate.cache.ehcache.EhCacheRegionFactory
</property>

3. Enable Caching on Entity Class Using Annotation:

@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Product {
    @Id
    private Long id;
    private String name;
}

4. Add ehcache.xml Configuration File (if using EHCache)

<ehcache>
    <defaultCache
        maxEntriesLocalHeap="1000"
        timeToLiveSeconds="300"
        eternal="false"
        overflowToDisk="false"/>
</ehcache>

When to Use Second-Level Cache

  • For read-mostly entities
  • For reference data that rarely changes
  • When you need to reduce DB load in a high-traffic application

13. What is JDBC batching in Hibernate, and how is it configured using hibernate.jdbc.batch_size?

JDBC batching is a performance optimization technique where multiple SQL statements are grouped together and sent to the database in a single batch instead of one by one. This reduces the number of database round-trips, improving the performance of bulk insert, update, or delete operations.

Hibernate supports JDBC batching out of the box, and it can be especially useful when you’re saving or updating multiple records in a loop.

How to Enable JDBC Batching in Hibernate

You can enable batching by setting the property hibernate.jdbc.batch_size in your configuration:

In hibernate.cfg.xml:

<property name="hibernate.jdbc.batch_size">20</property>

In application.properties (Spring Boot):

hibernate.jdbc.batch_size=20

14. What are the differences between eager and lazy fetching in Hibernate?

  • Lazy = Load only when needed β†’ better performance
  • Eager = Load everything upfront β†’ may waste resources

1. Lazy Fetching (FetchType.LAZY)

  • Default behavior for most relationships (like @OneToMany, @ManyToMany)
  • Related data is not loaded immediately
  • Data is fetched only when accessed (on-demand)
  • Improves performance by avoiding unnecessary data loading

Example:

@Entity
public class Student {
    @OneToMany(fetch = FetchType.LAZY)
    private List<Course> courses;
}

Courses won’t be fetched when you load the student. They will be fetched only when student.getCourses() is called.

2. Eager Fetching (FetchType.EAGER)

  • Related data is loaded immediately with the main entity
  • Fetches all associations at once, even if not needed
  • Can cause performance issues due to unnecessary data loading (especially in collections)

Example:

@Entity
public class Student {
    @OneToMany(fetch = FetchType.EAGER)
    private List<Course> courses;
}

Courses will be loaded as soon as the student is fetched.

15. How can you handle the N+1 select problem in Hibernate?

N+1 select problem

  • You fetch a list of entities (1 query), and
  • For each entity, Hibernate issues another query to load associated data (N queries),
  • So total N + 1 queries are executed instead of just 1 optimized query with a join.

Example Problem:

List<Student> students = session.createQuery("FROM Student").list();
for (Student s : students) {
    System.out.println(s.getCourses().size()); // Triggers separate query for each student
}

If there are 100 students, you’ll end up with 101 queries!

Solutions to the N+1 Select Problem

1. Use JOIN FETCH in HQL

Tell Hibernate to fetch associated entities using a single join query.

List<Student> students = session.createQuery(
    "SELECT s FROM Student s JOIN FETCH s.courses", Student.class
).list();

Result: Only one query is executed with an inner join.

2. Use @BatchSize Annotation

Fetch multiple lazy-loaded associations in batches rather than one-by-one.

@OneToMany(mappedBy = "student", fetch = FetchType.LAZY)
@BatchSize(size = 10)
private List<Course> courses;

Result: Reduces total queries (e.g., from 100 to 10).

3. Use EntityGraph (JPA 2.1+)

Specify what to fetch eagerly using a graph, without changing your entity mapping.

EntityGraph<?> graph = em.createEntityGraph("student-with-courses");
TypedQuery<Student> query = em.createQuery("SELECT s FROM Student s", Student.class);
query.setHint("javax.persistence.fetchgraph", graph);

JPA Interview Questions

1. What is JPA (Java Persistence API), and what is its main purpose in a Java application?

JPA (Java Persistence API) is a Java specification that defines a standard way to manage relational data in Java applications. It allows developers to map Java objects (entities) to database tables and perform operations like insert, update, delete, and fetch without writing direct SQL queries.

JPA acts as a bridge between Java code and the database by using annotations or XML to define how classes are stored in the database. It simplifies persistence logic by allowing developers to work with objects instead of JDBC code.

Main Purpose of JPA:

  • To map Java objects to relational database tables (ORM – Object-Relational Mapping)
  • To provide an abstraction layer over JDBC, reducing boilerplate code
  • To standardize data access across different frameworks like Hibernate, EclipseLink, etc.
  • To make data persistence simple, clean, and maintainable in enterprise applications

2. How does JPA differ from traditional ORM tools and JDBC?

JPA (Java Persistence API) is a high-level specification for object-relational mapping (ORM) in Java, which abstracts and simplifies the process of storing, retrieving, and managing data from relational databases. In contrast, JDBC (Java Database Connectivity) is a low-level API that requires developers to write detailed SQL queries and manage database connections, statements, and result sets manually. This makes JDBC more verbose and error-prone, whereas JPA allows developers to interact with the database using Java objects and annotations, reducing boilerplate code and improving maintainability.

When compared to traditional ORM tools like Hibernate, JPA serves as a standard interface, while Hibernate is an implementation of that interface. JPA provides a consistent programming model that can work across different ORM providers, whereas Hibernate includes additional features beyond the JPA specification, such as advanced caching, custom query language (HQL), and more tuning options. In short, JPA offers portability and simplicity, while tools like Hibernate provide more power and flexibility but may be tied to specific implementations.

3. What is the difference between JPA and Hibernate? How does JPA act as a specification and Hibernate as its implementation?

JPA is the interface (what to do), and Hibernate is the working engine (how to do it). You use JPA annotations and code, but Hibernate runs underneath and handles the actual database operations.

What JPA Provides

  • JPA gives you standard annotations like @Entity, @Id, @OneToMany, etc.
  • It also provides standard interfaces like EntityManager, Query, and EntityTransaction.
  • These are just rules and APIs β€” they don’t contain any working logic.

What Hibernate Does

  • Hibernate is a JPA implementation that takes your JPA code and does the real work behind the scenes.
  • When you call entityManager.persist(student), Hibernate is the one actually generating the SQL and executing it.
  • If you switch to another JPA provider like EclipseLink, it will follow the same JPA rules but use its own engine.

4. What is an @Entity in JPA? How is an entity class mapped to a database table?

In JPA, @Entity is an annotation used to tell the framework that a Java class should be mapped to a table in the database. When you mark a class with @Entity, JPA treats it as a persistent entity, meaning its objects can be stored, retrieved, and managed by the database through JPA.

How is an Entity Class Mapped to a Database Table?

When you annotate a class with @Entity, JPA will by default:

  • Use the class name as the table name
  • Use fields as columns
  • Use the field marked with @Id as the primary key

You can customize this mapping using annotations like @Table, @Column, and @GeneratedValue.

5. What are the different primary key generation strategies in JPA? Explain AUTO, IDENTITY, SEQUENCE, and TABLE.

In JPA, the @GeneratedValue annotation is used to automatically generate primary key values, and it supports 4 strategies:

@GeneratedValue(strategy = GenerationType.STRATEGY_NAME)

1. AUTO

  • Default strategy β€” JPA chooses the best strategy based on the database.
  • It may choose IDENTITY, SEQUENCE, or TABLE internally.
  • Suitable when you want to let JPA decide.
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

Use when: You want to write DB-independent code.

2. IDENTITY

  • Relies on auto-increment columns (supported by MySQL, SQL Server, etc.).
  • The database generates the ID during the INSERT.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

Use when: You are using databases like MySQL or SQL Server that support auto-increment fields.

3. SEQUENCE

  • Uses a database sequence object to generate IDs.
  • Supported by databases like PostgreSQL, Oracle, etc.
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "student_seq")
@SequenceGenerator(name = "student_seq", sequenceName = "student_sequence", allocationSize = 1)
private Long id;

Use when: Your database supports sequences and you want more control.

4. TABLE

  • Uses a separate table to store and generate primary key values.
  • Works on any database, but is slower and less efficient.
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "student_tbl")
@TableGenerator(name = "student_tbl", table = "id_generator", pkColumnName = "key_name", valueColumnName = "next_id", pkColumnValue = "student_id", allocationSize = 1)
private Long id;

Use when: You want full database independence, but it’s rarely used due to performance.

6. What are basic CRUD operations in JPA? How can you perform Create, Read, Update, and Delete using EntityManager?

CRUD stands for:

  • C – Create (insert new records)
  • R – Read (fetch data)
  • U – Update (modify existing records)
  • D – Delete (remove records)

In JPA, these operations are performed using the EntityManager interface.

1. Create (Insert)

To insert a new entity into the database, use persist():

Student student = new Student();
student.setName("Rahul");
student.setAge(22);

EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(student); // Adds new record
em.getTransaction().commit();
em.close();

2. Read (Find/Retrieve)

To fetch a record by its primary key, use find():

EntityManager em = emf.createEntityManager();
Student student = em.find(Student.class, 1L); // Retrieves student with ID 1
em.close();

You can also use JPQL:

List<Student> list = em.createQuery("SELECT s FROM Student s", Student.class).getResultList();

3. Update

To update an entity, use merge():

EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

Student student = em.find(Student.class, 1L);
student.setAge(25); // Change value
em.merge(student);  // Optional here, as the object is managed

em.getTransaction().commit();
em.close();

If the object is already managed (like after find()), you can skip merge() and just modify the object.

4. Delete

To delete an entity, use remove():

EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

Student student = em.find(Student.class, 1L);
em.remove(student); // Deletes the record

em.getTransaction().commit();
em.close();

7. What are the different entity states in JPA? Explain Transient, Managed, Detached, and Removed states.

StateDescription
TransientEntity is not associated with any EntityManager, and not stored in DB
ManagedEntity is in persistence context, tracked by EntityManager (synced to DB)
DetachedEntity was managed, but now it’s disconnected from EntityManager
RemovedEntity is marked for deletion, and will be deleted when transaction commits

1. Transient State

  • Object is created using new, but not yet persisted
  • No DB row exists, and no tracking by JPA
Student s = new Student(); // Transient
s.setName("Amit");

2. Managed (Persistent) State

  • Entity is now being tracked by JPA
  • Changes to the object will be automatically synchronized with the database
  • Occurs after calling persist() or find()
em.persist(s); // Now it's managed

3. Detached State

  • Entity was managed but is now disconnected (e.g., after em.close() or after transaction ends)
  • Changes are not saved unless reattached (via merge())
em.close(); // or after commit
s.setName("Updated"); // Not tracked anymore

4. Removed State

  • Entity is marked for deletion using em.remove()
  • Actual deletion occurs after transaction commit
em.remove(s); // s is now in removed state

Life Cycle Summary (Easy Flow):

new Student()             --> Transient  
em.persist(student)       --> Managed  
em.detach(student)        --> Detached  
em.remove(student)        --> Removed  

8. What are cascade types in JPA? Describe the use of ALL, PERSIST, MERGE, REMOVE, REFRESH, and DETACH.

Cascade types tell JPA which operations should be applied to the associated child entities when an operation is performed on the parent.

In simple words we can say, Cascade tells JPA: “If you do something to the parent, should I do the same to the child?”

For example, if you save or delete a Student, should JPA also save or delete the Courses linked to that student?

Cascade types are set using the cascade attribute:

@OneToMany(mappedBy = "student", cascade = CascadeType.ALL)
private List<Course> courses;
Cascade TypeDescription
ALLApplies all cascade operations
PERSISTSaves child when parent is saved
MERGEUpdates child when parent is updated
REMOVEDeletes child when parent is deleted
REFRESHReloads child when parent is refreshed
DETACHDetaches child when parent is detached

9. How are relationships managed in JPA? Explain with examples: @OneToOne, @OneToMany, @ManyToOne, and @ManyToMany.

JPA handles relationships using annotations like @OneToOne, @OneToMany, @ManyToOne, and @ManyToMany.

1. @OneToOne – One entity is related to exactly one other entity

Example: A Person has one Passport.

@Entity
public class Person {
    @Id
    private Long id;

    @OneToOne
    private Passport passport;
}

@Entity
public class Passport {
    @Id
    private Long id;

    private String passportNumber;
}

Bidirectional mapping can be done using mappedBy.

2. @OneToMany – One entity is related to many of another entity

Example: A Customer can have many Orders.

@Entity
public class Customer {
    @Id
    private Long id;

    @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL)
    private List<Order> orders;
}

@Entity
public class Order {
    @Id
    private Long id;

    @ManyToOne
    private Customer customer;
}

Typically used with @ManyToOne on the child side to manage the relationship.

3. @ManyToOne – Many entities are related to one entity

Example: Many Orders belong to one Customer.

@Entity
public class Order {
    @Id
    private Long id;

    @ManyToOne
    private Customer customer;
}

This is the owning side in most relationships.

4. @ManyToMany – Many entities are related to many others

Example: A Student can enroll in many Courses, and a Course can have many Students.

@Entity
public class Student {
    @Id
    private Long id;

    @ManyToMany
    @JoinTable(
        name = "student_course",
        joinColumns = @JoinColumn(name = "student_id"),
        inverseJoinColumns = @JoinColumn(name = "course_id")
    )
    private List<Course> courses;
}

@Entity
public class Course {
    @Id
    private Long id;

    @ManyToMany(mappedBy = "courses")
    private List<Student> students;
}

Creates a join table to manage many-to-many mapping.

10. How do you implement pagination in JPA using setFirstResult() and setMaxResults()?

JPA provides two methods on the Query or TypedQuery object for pagination:

  • setFirstResult(int startPosition) β†’ Starting row (zero-based)
  • setMaxResults(int maxResult) β†’ Number of records to fetch (page size)

Example:

Let’s say you want to fetch page 2 with 5 records per page (i.e., records 6–10):

int pageNumber = 2;
int pageSize = 5;

EntityManager em = emf.createEntityManager();

TypedQuery<Student> query = em.createQuery("SELECT s FROM Student s", Student.class);
query.setFirstResult((pageNumber - 1) * pageSize); // (2 - 1) * 5 = 5
query.setMaxResults(pageSize); // 5 results

List<Student> students = query.getResultList();

11. What is the role of @Version in JPA?

@Version in JPA is used to implement optimistic locking, which helps prevent conflicts when multiple users try to update the same database record at the same time.

Key Points:

  • It marks a field (like int, long, or Timestamp) as the version field of the entity.
  • JPA uses this field to track the version of each record in the database.
  • During an update, JPA includes the version in the SQL WHERE clause.
  • If the version doesn’t match (i.e., another user has updated it), JPA throws an OptimisticLockException and the update is rejected.

Leave a Comment

You must be to post a comment.

Similar Reads

Hi, Welcome back!
Forgot Password?
Don't have an account?  Register Now