JPA is the interface while Hibernate is the implementation.
Traditionally there have been multiple Java ORM solutions:
each implementation defining its own mapping definition or client API. The JPA expert group gathered the best of all these tools and so they created the Java Persistence API standard.
A standard persistence API is very convenient from a client point of view, making it relatively easy to switch one implementation with the other (although in practice it's not that simple because on large projects you'll have to use specific non-standard features anyway).
The standard JPA has pushed Java ORM competition to a new level and this can only lead to better implementations.
As explained in my book, High-Performance Java Persistence, Hibernate offers features that are not yet supported by JPA:
- extended identifier generators (hi/lo, pooled, pooled-lo)
- transparent prepared statement batching
- customizable CRUD (
@SQLInsert
, @SQLUpdate
, @SQLDelete
) statements
- static or dynamic collection filters (e.g.
@FilterDef
, @Filter
, @Where
) and entity filters (e.g. @Where
)
- mapping properties to SQL fragments (e.g. @Formula)
- immutable entities (e.g.
@Immutable
)
- more flush modes (e.g. FlushMode.MANUAL, FlushMode.ALWAYS)
- querying the second-level cache by the natural key of a given entity
- entity-level cache concurrency strategies
(e.g. Cache(usage = CacheConcurrencyStrategy.READ_WRITE))
- versioned bulk updates through HQL
- exclude fields from optimistic locking check (e.g.
@OptimisticLock(excluded = true)
)
- versionless optimistic locking (e.g.
OptimisticLockType.ALL
, OptimisticLockType.DIRTY
)
- support for skipping (without waiting) pessimistic lock requests
- support for Java 8 Date and Time
- support for multitenancy
- support for soft delete (e.g.
@Where
, @Filter
)
These extra features allow Hibernate to address many persistence requirements demanded by large enterprise applications.