Spring Data JPA: EntityManager Explained!

  • Post last modified:April 30, 2023
  • Reading time:5 mins read

Introduction

  • EntityManager is one of the key abstractions that JPA specification defines. EntityManager sits between the database and the application and plays the responsibility of managing the entity in context.
  • In this article, we will explore these responsibilities and try to learn about EntityManager.

JPA Architecture

Credits: https://openjpa.apache.org/builds/1.0.2/apache-openjpa-1.0.2/docs/manual/jpa_overview_arch.html

Entity

  • An Entity is basically a table representation of a relational database and an instance of that entity corresponds to a row in that table.
  • It’s a domain object in a persistent context.

Example of an Entity

  • @Entity is an annotation that we use to mark a POJO to the persistent context-aware entity.
  • @Table allows us to map entities to any custom-named database.
  • Other such annotations are @Id @SequenceGenerator @Column etc. that can be used inside the entity.
@Entity
@Table(name="ACCOUNTS")
public class Account {
    @Id @GeneratedValue(strategy= GenerationType.SEQUENCE, generator = "accounts_seq")
    @SequenceGenerator(name = "accounts_seq", sequenceName = "accounts_seq", allocationSize = 1)
    @Column(name = "user_id")
    private int userId;
    private String username;
    private String password;
    private String email;
    private Timestamp createdOn;
    private Timestamp lastLogin;
}

Managing Entity

  • Entities live in a persistent context (i.e. data store) and the persistent context defines the scope in which entity lifecycle such as creation, updation, removal, etc happens.
  • In order to manage the lifecycle of the entity, the EntityManager instance is used. EntityManager instance provides methods using which we can interact with persistent context.
  • Persistent Contexts where the entity & entitymanager lives are of two types, which are container-managed and application managed.

Container Managed

  • The container-managed persistent context will make sure that EntityManager instance is available when used inside the enterprise components such as @Component @Service @Controller etc.
  • Also, it will make sure that any transaction that exists between components and EntityManager instance is used then context gets propagated between components. Think about transaction scope when we make the call from one service component to another or make a controller to the service component.
  • In Container managed persistent context, we have the flexibility to inject entity managers and use methods on them.
@Service
public class ALogic {

    @PersistenceContext
    private EntityManager em;

    public void aMethod(){
         em.createQuery("select 1");
    }
}

Application Managed 

  • Application Managed persistent context is managed by the application and hence it will be the responsibility of the application which means the developer to create, open and manage the transaction boundary and hence the persistent context.
  • We can inject the EntityManagerFactory instance, but then getting a hold on the EntityManager instance and then managing the transaction will be the developer’s responsibility.
  • Sample logic would look like this: 
@Service
public class ALogic {
    
    @PersistenceUnit
    EntityManagerFactory emf;
    
    public void aMethod(){
        EntityManager em = emf.createEntityManager();
        EntityTransaction txn = em.getTransaction();
        Account account = getEntity();
        txn.begin();
        em.persist(account);
        txn.commit();
        em.close();
    }
}

Useful Methods

  • There are many methods on entitymanager that help us to interact with the database and manage the entity in the cache.

BTW, for simplicity, persistent context is basically a cache to manage the entity and interact with the database when necessary and update/modify/delete the entity

persist(Object entity)
// Make an instance managed and persistent.

merge(T entity)
// Merge the state of the given entity into the current persistence context.

flush()
// Synchronize the persistence context to the underlying database.

find(Class<T> entityClass, Object primaryKey)
// Find by primary key.

createQuery(String qlString)
// Create an instance of Query for executing a Java Persistence query language statement.

createNamedQuery(String name)
// Create an instance of Query for executing a named query (in the Java Persistence query language or in native SQL).

refresh(Object entity)
// Refresh the state of the instance from the database, overwriting changes made to the entity, if any.

remove(Object entity)
// Remove the entity instance.

detach(Object entity)
// Remove the given entity from the persistence context, causing a managed entity to become detached.

contains(Object entity)
// Check if the instance is a managed entity instance belonging to the current persistence context.

unwrap(Class<T> cls)
// Return an object of the specified type to allow access to the provider-specific API.

EntityManager vs Spring Data Repository

  • One would get confused when using EntityManager when they can achieve the same with the Spring Data Repository interface.
  • Spring Data JPA provides lots of helper methods to solve common interactions with databases, it suite of helper methods that saves us from writing a lot of code by providing easy to use of powerful APIs such as query generation feature.
  • So the point is, it makes sense to use EntityManager when Spring Data JPA is not enough and the query is complex enough and needs to fine-tune for performance.

Conclusion

  • In this article, we learned about Persistent Context, Entity, and EntityManager.
  • We also touch upon, when to use EntityManager and Spring Data Repository

Before You Leave

Leave a Reply