3.4.4.1. EntityManager

EntityManager - 用于处理持久化实体的主要 ORM 接口。

有关 EntityManager 和 DataManager 之间差异的信息,请参阅 DataManager 与 EntityManager

可以通过调用 Persistence 接口的 getEntityManager() 方法获取 EntityManager 的引用。获取到的 EntityManager 实例绑定到当前事务,在一个事务中对 getEntityManager() 方法的所有调用都将返回同一个 EntityManager 实例。在事务结束后便不能再使用此事务的 EntityManager 实例。

EntityManager 的实例包含 持久化上下文 ,持久化上下文存储了从数据库加载的或新创建的一组实体实例。持久化上下文是处于事务中的数据缓存。EntityManager 会自动将持久化上下文中所做的所有更改在事务提交时或者调用 EntityManager.flush() 方法时更新到数据库。

CUBA 应用程序中使用的 EntityManager 接口主要复制标准 javax.persistence.EntityManager 接口。下面是它的主要方法:

  • persist() – 将实体的新实例添加到持久化上下文中。提交事务时,会使用 INSERT SQL 语句在 DB 中创建相应的记录。

  • merge() – 通过以下方式将游离实例的状态复制到持久化上下文:从 DB 中加载相同标识符的实例,并将传递的游离实例的状态复制到这个加载的实例,然后返回加载的托管实例。之后,应该使用返回的托管实例。在事务提交时,会使用 UPDATE SQL 语句将该实体的状态存储到 DB 中。

  • remove() – 从数据库中删除对象,或者,如果启用了软删除模式,则只设置 deleteTsdeletedBy 属性。

    如果传递的实例处于游离状态,则首先执行 merge() 方法。

  • find() – 通过标识符加载实体实例。

    当向数据库发送请求时,系统会将传递的视图作为参数传递给该方法。因此,持久化上下文将包含加载了所有视图属性的对象图。如果没有传递视图,则默认使用 _local 视图。

  • createQuery() – 创建一个 QueryTypedQuery 对象来执行JPQL 查询

  • createNativeQuery() – 创建一个 Query 对象来执行SQL 查询

  • reload() – 使用提供的视图重新加载实体实例。

  • isSoftDeletion() – 检查 EntityManager 是否处于软删除模式。

  • setSoftDeletion() – 为 EntityManager 设置软删除模式。

  • getConnection() – 返回当前事务对应的连接。这种连接不需要主动关闭,它会在事务完成时自动关闭。

  • getDelegate() – 返回 ORM 实现提供的 javax.persistence.EntityManager

服务中使用 EntityManager 的示例:

@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;
    }
}
部分实体

默认情况下,在 EntityManager 中,视图仅影响引用属性,本地属性会被全部加载。

如果将视图的loadPartialEntities属性设置为 true,则可以强制 EntityManager 加载 部分(partial) 实体(像DataManager所做的一样)。但是,如果加载的实体是缓存的(cached),则忽略此视图属性,仍将加载实体的所有本地属性。