JPA vs Hibernate — Specification vs Implementation
Fast recall
Quick revision
Core answer
Session (extends EntityManager), HQL (superset of JPQL), @NaturalId, second-level caching, multi-tenancy, and StatelessSession. Code to JPA interfaces (jakarta.persistence.*) when you want portability — you can swap providers via configuration. Drop to `org.hibernate.*` only for features JPA does not cover, like natural ID lookups or scrollable batch reads. Spring Data JPA sits on top of JPA's EntityManager, so Hibernate is just the engine underneath.Whether the candidate understands the spec-vs-implementation relationship rather than treating JPA and Hibernate as interchangeable terms
Saying 'JPA is a framework' — it's a specification with no implementation. You cannot run JPA without a provider like Hibernate, EclipseLink, or OpenJPA
Explain why coding to JPA interfaces is preferred for portability, and name specific Hibernate-only features that justify dropping down to the native API
Interview-ready guide
Interview answer
JPA and Hibernate are not synonyms, even though they are used together so often that the distinction blurs. Getting this right shows architectural understanding rather than just framework familiarity.
JPA — the specification:
- Defined in
javax.persistence.*(JPA 2.x) orjakarta.persistence.*(JPA 3.x and Jakarta EE) - Annotations like
@Entity,@Table,@OneToMany,@ManyToOne,@Id,@GeneratedValueare JPA standard EntityManager,EntityManagerFactory,TypedQuery, JPQL — all JPA APIs- Any compliant implementation can run code written against JPA APIs
Hibernate — the implementation:
- The dominant JPA implementation, used by default in Spring Boot
Session(Hibernate-specific) extendsEntityManager;SessionFactoryextendsEntityManagerFactory- Hibernate-specific features:
@BatchSize,@Fetch,@NaturalId,@Type,@Filter— use only when JPA has no equivalent
Spring Data JPA:
- Sits above JPA —
JpaRepositorycallsEntityManager; Hibernate is just the JPA provider underneath - Adds derived query methods,
@QueryJPQL,Specification, and pagination on top of standard JPA APIs
Default position: code to JPA, escape to Hibernate when justified.
JPA vs Hibernate — Specification vs Implementation
Direct Answer
JPA (Jakarta Persistence API) is a specification — a set of interfaces, annotations, and behavioral contracts. It has no implementation and cannot run on its own. Hibernate is the dominant JPA provider that implements the spec and adds extras: Session (extends EntityManager), HQL (superset of JPQL), @NaturalId, second-level caching, multi-tenancy, and StatelessSession. Code to JPA interfaces (jakarta.persistence.*) when you want portability — you can swap providers via configuration. Drop to org.hibernate.* only for features JPA does not cover, like natural ID lookups or scrollable batch reads. Spring Data JPA sits on top of JPA's EntityManager, so Hibernate is just the engine underneath.
Code Example
JPA is a specification in jakarta.persistence — a portable API. Hibernate is one of its implementations that adds non-standard features (second-level cache, @Formula, criteria extensions). Code that uses only JPA types is portable; code that imports org.hibernate.* is locked to Hibernate.
// ---------- 100% JPA (portable to EclipseLink, OpenJPA, DataNucleus) ----------
@Entity
@Table(name = "users")
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
@Column(nullable = false, unique = true) private String email;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Order> orders = new ArrayList<>();
}
@Repository
public class UserDao {
@PersistenceContext private EntityManager em; // JPA API
public List<User> findByDomain(String domain) {
return em.createQuery(
"SELECT u FROM User u WHERE u.email LIKE :d", User.class) // JPQL (portable)
.setParameter("d", "%@" + domain).getResultList();
}
}
// ---------- Hibernate-only (not portable) ----------
@Entity
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) // Hibernate
@org.hibernate.annotations.DynamicUpdate // Hibernate
public class Product {
@Id private Long id;
@org.hibernate.annotations.Formula("(SELECT AVG(r.stars) FROM reviews r WHERE r.product_id = id)")
private Double avgRating; // computed column — Hibernate extension
}
// Dropping to the native Hibernate Session:
@Autowired private EntityManager em;
Session session = em.unwrap(Session.class);
session.enableFilter("active").setParameter("flag", true); // Hibernate filters
- Every Spring Data JPA project transitively uses Hibernate as the provider unless explicitly switched. You are already on Hibernate — the question is whether your code depends on its extensions.
- Stay in
jakarta.persistence.*for 95% of code; reach fororg.hibernate.*only when you need features JPA does not define (multi-tenancy filters,@Formula,@Any). - JPA's
EntityManageris a thin wrapper —em.unwrap(Session.class)gives you the HibernateSessionfor advanced use without rewriting repositories.
Common Mistakes & Pitfalls
Saying 'JPA is a framework' — it's a specification with no implementation. You cannot run JPA without a provider like Hibernate, EclipseLink, or OpenJPA
Check your understanding
Answer these without looking back at the article.
- What are other JPA providers besides Hibernate, and why are they rarely used?
- When would you use Hibernate-specific features instead of sticking to JPA?
- What is the difference between JPQL and HQL?
- How do you migrate from `javax.persistence` to `jakarta.persistence` in a large codebase?
Related interview prep categories
2Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.