Core Methods
Core Methods Interview with follow-up questions
1. Can you explain the difference between the get() and load() methods in Hibernate?
Both methods retrieve a persistent entity by its primary key, but they differ in when the database is hit and how they handle missing records — a classic Hibernate interview distinction.
get() / find() — immediate load
Hits the database immediately and returns the fully initialized entity, or null if no row exists:
// Hibernate Session API
User user = session.get(User.class, 42L);
if (user == null) {
// handle not found
}
// JPA EntityManager equivalent (preferred in modern code)
User user = em.find(User.class, 42L);
load() / getReference() — proxy / lazy load
Returns a proxy object without hitting the database. The SQL is issued only when a non-identifier property is first accessed. If the row does not exist, accessing the proxy throws EntityNotFoundException (or ObjectNotFoundException with the native Hibernate API):
// Hibernate Session API
User proxy = session.load(User.class, 42L);
// No SQL yet — proxy is returned immediately
System.out.println(proxy.getName()); // SQL fires here; throws if row missing
// JPA EntityManager equivalent
User proxy = em.getReference(User.class, 42L);
When to use each
| Scenario | Method |
|---|---|
| You need to read/display the entity | find() / get() |
| You only need the object as a foreign key reference (e.g., setting a relationship without reading the data) | getReference() / load() |
| You need null-safe not-found handling | find() / get() |
Key interview gotchas
load()/getReference()is a performance optimization when you need an entity reference solely to satisfy a foreign key constraint — it avoids a round-trip to the database.- In Hibernate 6,
session.load()is effectively deprecated in favor ofsession.getReference(), which aligns with the JPA standard. - Accessing a
load()proxy after the session is closed throwsLazyInitializationException. - Both methods check the first-level cache before hitting the database — if the entity is already in the session, no SQL is issued regardless of which method you call.
Follow-up 1
What is the return type of these methods?
The get() method returns the object from the database or null if the object does not exist.
The load() method returns a proxy object that represents the requested object. The actual object is loaded from the database when a method is called on the proxy object.
Follow-up 2
In what scenarios would you prefer to use get() over load() and vice versa?
You would prefer to use get() over load() when you want to immediately retrieve the object from the database and handle the case when the object does not exist by checking for null.
On the other hand, you would prefer to use load() over get() when you are confident that the object with the provided identifier exists in the database and you want to avoid the immediate database query. However, you need to be cautious when using load() as it throws an exception if the object does not exist.
Follow-up 3
What happens when there is no record with the provided identifier in the database?
If there is no record with the provided identifier in the database:
- The
get()method returnsnull. - The
load()method throws an exception.
2. What is the purpose of the save() method in Hibernate?
In Hibernate 6 with jakarta.persistence, save() is a Hibernate-proprietary method that is effectively superseded by the JPA standard persist(). Understanding both — and their differences — is important for interviews.
save() (Hibernate-native, legacy)
save() is defined on Hibernate's Session interface. It always assigns an identifier to the entity (triggering an INSERT immediately if using IDENTITY generation), and it returns the generated identifier:
Session session = sessionFactory.openSession();
session.beginTransaction();
User user = new User("Alice");
Long id = (Long) session.save(user); // returns the generated ID
session.getTransaction().commit();
persist() (JPA standard, preferred)
persist() is defined in the jakarta.persistence.EntityManager API. It makes a transient entity managed and persistent, but does not guarantee an immediate INSERT — the actual SQL may be deferred until flush. It returns void:
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
User user = new User("Alice");
em.persist(user); // void return
em.getTransaction().commit(); // INSERT happens at flush/commit
Key differences
| Aspect | save() |
persist() |
|---|---|---|
| API | Hibernate Session |
JPA EntityManager |
| Return type | Serializable (the generated ID) |
void |
| Outside transaction | Executes INSERT immediately | Throws TransactionRequiredException |
| Standard | Hibernate-proprietary | JPA standard (portable) |
Modern recommendation
In Spring Boot 3 with Hibernate 6, always use the JPA API (persist(), merge(), remove(), find()) unless you specifically need a Hibernate-native feature. Spring Data JPA's repository.save() calls persist() for new entities and merge() for existing ones (determined by whether the ID is set).
Key interview gotchas
session.save()called outside a transaction still executes — this can silently skip transactional rollback behavior.- With
SEQUENCEorTABLEgeneration strategies,persist()may still hit the database to fetch the next sequence value even before flush. - Do not confuse Spring Data's
repository.save()(which is smart about new vs existing) with Hibernate'ssession.save()(which always inserts).
Follow-up 1
What is the return type of the save() method?
The return type of the save() method in Hibernate is Serializable. It returns the identifier (primary key) of the saved object.
Follow-up 2
What happens if we call the save() method without setting the primary key?
If we call the save() method without setting the primary key, Hibernate will generate a primary key value for the object automatically. This is typically done using an identifier generator strategy configured in the Hibernate mapping.
Follow-up 3
Can you explain the difference between save() and persist() methods?
Both save() and persist() methods in Hibernate are used to save an object into the database. However, there are some differences:
- The save() method returns the identifier (primary key) of the saved object, while the persist() method does not return anything.
- The save() method can be called before or after the transaction is committed, while the persist() method can only be called within an active transaction.
- The save() method generates a new identifier value for a transient object, while the persist() method throws an exception if called on a transient object with a non-null identifier.
3. How does the update() method work in Hibernate?
The update() method re-associates a detached entity with the current session and schedules an UPDATE for its state. It is a Hibernate-native method on Session; the JPA equivalent is merge().
How update() works
When an entity is detached (session closed, or explicitly detached), changes to it are not tracked. update() brings it back into the persistent state:
// Entity was loaded in a previous session and is now detached
User detachedUser = ...; // fetched earlier, session is closed
detachedUser.setEmail("[email protected]");
Session session = sessionFactory.openSession();
session.beginTransaction();
session.update(detachedUser); // re-attaches and marks for UPDATE
session.getTransaction().commit(); // UPDATE fires at flush
update() vs merge()
| Aspect | update() |
merge() |
|---|---|---|
| API | Hibernate Session (proprietary) |
JPA EntityManager (standard) |
| If already in session | Throws NonUniqueObjectException |
Copies state into managed instance, returns it |
| Return | void |
Returns the managed (merged) entity |
| Safe for detached objects from unknown sessions | No | Yes |
Modern recommendation: use merge()
merge() is safer and preferred in practice because it handles the case where a managed instance with the same ID already exists in the session:
User managedUser = em.merge(detachedUser); // returns the managed copy
Spring Data JPA's repository.save() calls merge() internally for entities that already have an ID set.
Dirty checking vs explicit update()
For entities that are already persistent (loaded in the current session), you do not need to call update() at all — Hibernate's dirty checking mechanism detects property changes automatically and generates the UPDATE at flush time:
User user = em.find(User.class, 1L);
user.setEmail("[email protected]");
// No explicit update() call needed — dirty check handles it
em.getTransaction().commit();
Key interview gotchas
- Calling
session.update()on an entity when another instance with the same ID is already in the session throwsNonUniqueObjectException— usemerge()instead. update()always schedules an UPDATE even if nothing changed;merge()may optimize this away via dirty checking on the merged instance.- In Hibernate 6,
session.update()is deprecated in favor ofsession.merge()to align with JPA.
Follow-up 1
What happens if we call update() on a transient object?
If we call update() on a transient object, Hibernate will throw an exception. A transient object is an object that is not associated with any database row. In order to update an object, it must be in the persistent state, meaning it must be associated with a database row. To update a transient object, we need to first make it persistent by either saving it using the save() method or retrieving it using the get() or load() methods.
Follow-up 2
What is the difference between update() and merge() methods?
The update() and merge() methods in Hibernate are used to update the state of persistent objects, but they have some differences:
The update() method is used to update the state of a persistent object with the new values from the object passed as a parameter. It throws an exception if the object is transient.
The merge() method is used to merge the state of a detached object with the state of a persistent object. It returns the persistent object with the merged state. If the object is transient, it will be saved as a new row in the database.
In summary, the update() method updates the state of a persistent object in place, while the merge() method merges the state of a detached object with a persistent object and returns the merged object.
Follow-up 3
Can you explain the scenario where update() method can lead to an exception?
The update() method in Hibernate can lead to an exception in the following scenario:
- If we call update() on a transient object, Hibernate will throw a TransientObjectException. A transient object is an object that is not associated with any database row. In order to update an object, it must be in the persistent state, meaning it must be associated with a database row. To update a transient object, we need to first make it persistent by either saving it using the save() method or retrieving it using the get() or load() methods.
4. What is the role of the evict() method in Hibernate?
The evict() method removes a specific entity instance from the first-level cache (the session cache), detaching it from the current session without deleting it from the database.
What it does
User user = session.get(User.class, 1L);
// user is now in the L1 cache and tracked for dirty checking
session.evict(user);
// user is detached — no longer tracked
// further changes to user will NOT be flushed to the database
After evict(), the object is in the detached state. The database row is unchanged.
When to use evict()
- Memory management in batch processing: when processing thousands of entities, the session cache grows indefinitely. Evicting processed entities prevents
OutOfMemoryError:
for (int i = 0; i < records.size(); i++) {
session.persist(records.get(i));
if (i % 50 == 0) {
session.flush(); // write to DB
session.clear(); // evict everything (more common than evict() per-entity)
}
}
- Preventing accidental dirty writes: evict an entity when you want to read it for reporting without risking any modification being flushed.
evict() vs clear() vs detach()
| Method | Scope | API |
|---|---|---|
session.evict(entity) |
Single entity | Hibernate Session |
session.clear() |
All entities in session | Hibernate Session |
em.detach(entity) |
Single entity | JPA EntityManager (standard) |
em.detach() is the JPA-standard equivalent of session.evict() and is preferred in modern code.
Key interview gotchas
evict()does not flush pending changes first — if you modified the entity and then evict without flushing, those changes are lost.- For bulk processing,
StatelessSessionis often a better choice thanSession+ manual eviction — it bypasses the L1 cache entirely and has lower overhead. session.clear()is equivalent to evicting every entity at once and is commonly used in batch loops alongsidesession.flush().
Follow-up 1
What happens to the state of the object after evict() method is called?
After the evict() method is called, the object becomes detached from the session. This means that any changes made to the object will not be automatically synchronized with the database. The object will no longer be managed by Hibernate and any further operations on the object will not be tracked by Hibernate.
Follow-up 2
Can you explain the difference between evict() and remove() methods?
The evict() method in Hibernate removes a persistent instance from the session cache and detaches it from the session. It does not delete the object from the database.
On the other hand, the remove() method is used to delete an object from the database. It not only removes the object from the session cache but also deletes it from the database.
In summary, evict() removes the object from the session cache without deleting it from the database, while remove() deletes the object from both the session cache and the database.
Follow-up 3
What is the use case for the evict() method?
The evict() method in Hibernate is useful in scenarios where you want to remove an object from the session cache without deleting it from the database. This can be beneficial in situations where you have a large number of objects in the session cache and you want to release memory by removing unnecessary objects. It can also be used when you want to detach an object from the session to prevent any further changes from being tracked by Hibernate.
5. Can you explain the purpose of the remove() method in Hibernate?
The remove() method (JPA standard) or delete() method (Hibernate-native) marks a persistent entity for deletion. The actual DELETE SQL is issued when the session is flushed, which typically happens at transaction commit.
Usage
// JPA standard (preferred)
User user = em.find(User.class, 1L);
em.remove(user);
// DELETE FROM users WHERE id = 1 fires at flush/commit
// Hibernate-native equivalent (legacy)
User user = session.get(User.class, 1L);
session.delete(user); // deprecated in Hibernate 6 — use remove()
In Hibernate 6, session.delete() is deprecated. Use session.remove() (which mirrors the JPA API) instead.
Entity must be managed
The entity passed to remove() must be in the persistent (managed) state. Passing a detached instance throws IllegalArgumentException in JPA:
User detached = ...; // detached entity
em.remove(detached); // throws IllegalArgumentException
// Correct approach:
User managed = em.merge(detached);
em.remove(managed);
Cascade delete
If the entity has associations with CascadeType.REMOVE (or CascadeType.ALL), removing the parent also removes the associated children:
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List items;
orphanRemoval = true also deletes child entities when they are removed from the collection, even without calling remove() explicitly.
Key interview gotchas
remove()requires the entity to be managed — alwaysfind()first if working with an ID.- Calling
remove()on a detached object is a common mistake; the fix is tomerge()first orfind()again in the current session. orphanRemovalandCascadeType.REMOVEare related but distinct:orphanRemovalfires when the child is disassociated from the collection;CascadeType.REMOVEfires when the parent is deleted.- The DELETE SQL is deferred until flush — within the same transaction you can still cancel by rolling back.
Follow-up 1
What is the state of the object after remove() method is called?
After the remove() method is called, the object becomes detached from the Hibernate session. It is no longer associated with any persistent context and any further changes made to the object will not be synchronized with the database.
Follow-up 2
What happens if we call remove() on a detached object?
If we call remove() on a detached object, Hibernate will throw a NonUniqueObjectException. This exception is thrown because Hibernate cannot determine which persistent instance of the object to delete from the database.
Follow-up 3
Can you explain the difference between remove() and delete() methods?
The remove() method is a Hibernate-specific method that marks an object for deletion and removes it from the session cache. The actual deletion from the database occurs when the session is flushed or when a transaction is committed.
On the other hand, the delete() method is a JPA standard method that directly deletes an object from the database. It does not remove the object from the session cache and does not require a session flush or transaction commit to perform the deletion.
Live mock interview
Mock interview: Core Methods
- 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.