Подтвердить что ты не робот

Различные способы получения EntityManager

Обычная идиома, которую я вижу для создания EntityManager, выглядит примерно так:

public class BaseDao {
    private static final String PERSISTENCE_UNIT_NAME = "Employee";

    EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

    public EntityManager getEntityManager() {
      return factory.createEntityManager();
    } 
}

Тогда это используется так:

Employee emp = new Employee();
emp.setName("Joe M");
getEntityManager().persist(emp);

Вопрос: почему бы не сделать это так:

public class BaseDao{
    private static final String PERSISTENCE_UNIT_NAME = "Employee";
    EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
    private EntityManager entityManager = null;


public void setEntityManger() {
    EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
    this.entityManager = factory.createEntityManager();

    }

    public EntityManager getEntityManager() {
        return this.entityManager;
    }
}

Другими словами, есть ли необходимость всегда получать менеджер сущностей через factory.createEntityManager()? или он может быть создан как переменная экземпляра (или даже статическая переменная) и получен таким образом?

Чтобы уточнить, я говорю о среде, которая не использует контейнеры EJB или Spring.

Благодарю.

4b9b3361

Ответ 1

Существует два способа создания экземпляров EntityManager.

Один способ - для приложений SDK, и я часто использую его в модульном тестировании. Вот что у вас есть в вашем примере:

EntityManagerFactory factory = 
  Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

В корпоративных приложениях вы позволяете контейнеру создавать их для вас и вставлять их при необходимости.

EntityManager - это просто оболочка для соединения JDBC. Это очень легкий вес и может быть создан и уничтожен без потери производительности.

Помните, что EntityManager не является потокобезопасным, поэтому, если у вас есть один экземпляр, вам может потребоваться синхронизировать доступ к нему. Смотрите основы транзакций для деталей.


Вот как бы я это сделал (примерно):

public class BaseDao{
  private static final String PERSISTENCE_UNIT_NAME = "Employee";
  private static EntityManagerFactory factory = 
    Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

  public void create(MyEntiy person){
    EntityManager em = factory.createEntityManager();
    em.getTransaction().begin();
    // do what ever you need 
    em.getTransaction().commit();
    em.close();
  }

  // add more methods to the dao.
}

Как только вы получите этот прототип и будете готовы, вы можете использовать универсальный DAO.

Ответ 2

Сегодня вам, вероятно, стоит подумать о Spring-data и @PersistanceUnit для управления вашим EntityManager.

EntityManager - это больше, чем просто оболочка-оболочка для соединения JDBC. Он определяет область действия персистентного контекста, который определяет единицу работы, которая должна выполняться при фиксации транзакции (когда вы сбрасываете запросы в базу данных). В контексте постоянства вам также гарантируется, что данный объект в базе данных приведет к тому же объекту Java, независимо от того, загружаете ли вы его напрямую или обращаетесь к нему через отношение OneToMany другого объекта.

Относительно первоначального вопроса о получении EntityManagerFactory в неподрессоренных условиях. Вы просто звоните

Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

Этот метод является статическим методом фабрики, и в зависимости от реализации JPA вы либо получаете один и тот же экземпляр для того же PU, либо неглубокую оболочку, которая оборачивает основной сеанс персистентности (из которых по одному на PU).