3.4.4.1. EntityManager

EntityManager – main ORM interface for working with persistent entities.

See DataManager vs. EntityManager for information on differences between EntityManager and DataManager.

Reference to EntityManager may be obtained via the Persistence interface by calling its getEntityManager() method. The retrieved instance of EntityManager is bound to the current transaction, i.e. all calls to getEntityManager() as part of one transaction return one and the same instance of EntityManager. After the end of the transaction using the corresponding EntityManager instance is impossible.

An instance of EntityManager contains a persistence context – a set of instances loaded from the database or newly created. The persistence context is a data cache within a transaction. EntityManager automatically flushes to the database all changes made in its persistence context on the transaction commit or when the EntityManager.flush() method is called.

The EntityManager interface used in CUBA applications mainly copies the standard javax.persistence.EntityManager interface. Let us have a look at its main methods:

  • persist() – adds a new instance of the entity to the persistence context. When the transaction is committed a corresponding record is created in DB using SQL INSERT.

  • merge() – copies the state of detached instance to the persistence context the following way: an instance with the same identifier gets loaded from DB and the state of the passed Detached instance is copied into it and then the loaded Managed instance is returned. After that you should work with the returned Managed instance. The state of this entity will be stored in DB using SQL UPDATE on transaction commit.

  • remove() – removes an object from the database, or, if soft deletion mode is turned on, sets deleteTs and deletedBy attributes.

    If the passed instance is in Detached state, merge() is performed first.

  • find() – loads an entity instance by its identifier.

    When forming a request to the database the system considers the view which has been passed as a parameter to this method. As a result, the persistence context will contain a graph of objects with all view attributes loaded. If no view is passed, the _local view is used by default.

  • createQuery() – creates a Query or TypedQuery object for executing a JPQL query.

  • createNativeQuery() – creates a Query object to execute an SQL query.

  • reload() – reloads the entity instance with the provided view.

  • isSoftDeletion() – checks if the EntityManager is in soft deletion mode.

  • setSoftDeletion() – sets soft deletion mode for this EntityManager.

  • getConnection() – returns a java.sql.Connection, which is used by this instance of EntityManager, and hence by the current transaction. Such connection does not need to be closed, it will be closed automatically when the transaction is complete.

  • getDelegate() – returns javax.persistence.EntityManager provided by the ORM implementation.

Example of using EntityManager in a service:

@Service(SalesService.NAME)
public class SalesServiceBean implements SalesService {

    @Inject
    private Persistence persistence;

    @Override
    public BigDecimal calculateSales(UUID customerId) {
        BigDecimal result;
        // start transaction
        try (Transaction tx = persistence.createTransaction()) {
            // get EntityManager for the current transaction
            EntityManager em = persistence.getEntityManager();
            // create and execute Query
            Query query = em.createQuery(
                    "select sum(o.amount) from sample$Order o where o.customer.id = :customerId");
            query.setParameter("customerId", customerId);
            result = (BigDecimal) query.getFirstResult();
            // commit transaction
            tx.commit();
        }
        return result != null ? result : BigDecimal.ZERO;
    }
}
Partial entities

By default, in EntityManager, a view affects only reference attributes, i.e. all local attributes are loaded.

You can force EntityManager to load partial entities if you set the loadPartialEntities attribute of the view to true (for example, DataManager does this). However, if the loaded entity is cached, this view attribute is ignored and the entity will still be loaded with all local attributes.