JPA EntityManager, как это работает?

Извините за нубский вопрос, но у меня проблемы с JPA+Hibernate, поэтому я подумал, что у меня что-то не ясно. У меня есть несколько объектов, скажем, A, B, C, D, и я закодировал AMethods, BMethods, CMethods, DMethods. Каждый из классов *Methods содержит инициализацию EntityManager через EntityManagerFactory и некоторые методы, которые в основном выполняют запросы. Я не знаю, следует ли мне использовать одноэлементный шаблон (чтобы у меня был EntityManager для каждого класса * Method) или мне нужно открывать и закрывать EntityManager каждый раз, когда я выполняю запрос или я сохраняю/удаляю объект... можешь мне помочь??


person Raffo    schedule 07.09.2009    source источник


Ответы (4)


В типичном приложении JPA/Hibernate вы не размещаете логику постоянства в самих классах сущностей. Это большое изменение в философии дизайна по сравнению со старыми приложениями EJB 2.x. Вместо этого многие приложения создают слой объектов доступа к данным — отдельно от сущностей, — которые используют экземпляры EntityManager для запроса, загрузки и сохранения сущностей. Часто это синглтоны, а экземпляры диспетчера сущностей внутри DAO являются локальными для потока.

Если вы используете такую ​​платформу, как Spring, управление экземплярами и транзакциями EntityManager происходит полностью автоматически. То же самое с EJB 3, хотя я не использовал его в большом проекте. Я бы посоветовал прочитать главу документации Spring на Объектно-реляционное сопоставление доступ к данным. Даже если в конечном итоге вы не будете использовать Spring в своем приложении, в этой главе даются хорошие советы о том, как структурировать ваше приложение многоуровневым способом, который отделяет проблемы сохранения от сохраняемых сущностей. Удачи!

person Rob H    schedule 07.09.2009
comment
Я не использую Spring и использую DAO, как объяснено (DAO — это классы *Methods), но все они используют один и тот же контекст персистентности. Правильно ли выполнять createEntityManager в AMethods, а также в BMethods, даже если они используют один и тот же контекст сохранения?? - person Raffo; 07.09.2009

EntityManager связан с контекстом сохраняемости. Используйте шаблон singleton, если все ваши сущности связаны с одним контекстом. Вы используете jpa на стороне сервера, верно? Если это так, вы можете инициализировать EntityManager в методах инициализации, таких как init() в сервлетах.

person merin    schedule 07.09.2009
comment
Я использую один и тот же контекст сохранения, каждая сущность связана с одним контекстом. Я использую jpa на стороне сервера, но также использую его в java-приложении, работающем в фоновом режиме... Я должен инициализировать контекст в этом приложении и создать *Methods, передавая EntityManager в качестве параметра?? - person Raffo; 07.09.2009
comment
Да, если служба и ваше фоновое приложение являются разными приложениями, необходимо инициировать EntityManager для обоих. Я думаю, что сериализация экземпляра EntityMaanger будет сложной задачей. - person merin; 07.09.2009
comment
Используйте Spring, используйте Hibernate. Почему Эйб? - person merin; 07.09.2009
comment
Я просто использовал JPA, как описано здесь: java.sun.com/ javaee/5/docs/tutorial/doc/bnbpz.html. Что-то не так с моим подходом? - person Raffo; 07.09.2009
comment
JPA используется как подчеркивание ORM, как драйвер. Почему вы не используете ORM без каких-либо абстракций? - person merin; 07.09.2009
comment
Итак, вы думаете, что я должен создавать объекты и позволить JPA делать все остальное? Я использовал подход, описанный в теме, потому что мне было проще получить все сущности, удовлетворяющие условию (используя запросы), и одновременно сохранить множество сущностей... - person Raffo; 07.09.2009

Надеюсь, это фото ответит на ваш вопрос. введите здесь описание изображения

person Ali Yeganeh    schedule 21.05.2020

именно так!

открытый интерфейс ProtokollDAOService {

/**
 * Fügt ein Protokollobjekt in die Datenbank hinzu.
 * 
 * @param object
 */
public void addProtokoll (ProtokollModel object);

/**
 * Läd aus einer Datenbank Protokoll-Elemente und fügt sie in eine Liste hinzu
 * 
 * @return List <ProtokollModel> Liste mit Protokoll-Elementen 
 */
public List <ProtokollModel> getProtokolls ();

/**
 * Liefert ein Protokoll-Element aus der Datenbank anhand der ID; 
 * 
 * @param id
 * @return ProtokollModel Protokoll-Element 
 */
public ProtokollModel getProtokollById (long id);

/**
 * Liefert eine Liste von Protokoll-Elementen anhand des Problem-Status 
 * 
 * @param solved
 * @return List <ProtokollModel> Liste mit Protokoll-Elementen   
 */
public List <ProtokollModel> getProtokollByProblemStatus (boolean solved);

/**
 * Liefert eine Liste von Protokoll-Elementen anhand des Aufgaben-Status 
 * 
 * @param ready
 * @return List <ProtokollModel> Liste mit Protokoll-Elementen
 */
public List <ProtokollModel> getProtokollByAufgabenStatus (boolean ready);

/**
 * Liefert ein Protokoll-Element anhand des Problems
 * 
 * @param problem
 * @return List <ProtokollModel> Liste mit Protokoll-Elementen   
 */
public List <ProtokollModel> getProtokollByProblem (String problem);

/**
 * Liefert ein Protokoll-Element anhand der Aufgabe
 * 
 * @param aufgabe
 * @return List <ProtokollModel> Liste mit Protokoll-Elementen
 */
public List <ProtokollModel> getProtokollByAufgabe (String aufgabe);

/**
 * Ausgabe der Protokoll-Tabelle
 * 
 */
public void printTable ();

}

открытый класс ProtokollDAOImpl реализует ProtokollDAOService { private static final String PERSISTENCE_UNIT_NAME = "ProtokollManager"; частная EntityManagerFactory entityFactory;

/*
 * (non-Javadoc)
 * 
 * @see util.ProtokollDAOService#addProtokoll(model.ProtokollModel)
 */
public void addProtokoll(ProtokollModel object) {
    try
    {
        entityFactory = Persistence
                .createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
        EntityManager em = entityFactory.createEntityManager();

        // Transaction starten
        em.getTransaction().begin();

        // Object zum speichern
        em.persist(object);

        // commit senden an die DB / Transaction abschliessen
        em.getTransaction().commit();

        // DB connection schliessen
        em.close();
    }
    catch (Exception e)
    {
        Logger.console("Exception wurde ausgelösst! " + e);
        e.printStackTrace();
    }
}

/*
 * (non-Javadoc)
 * 
 * @see util.ProtokollDAOService#getProtokollByAufgabe(java.lang.String)
 */
public List<ProtokollModel> getProtokollByAufgabe(String aufgabe) {
    // TODO Auto-generated method stub
    return null;
}

/*
 * (non-Javadoc)
 * 
 * @see util.ProtokollDAOService#getProtokollByAufgabenStatus(boolean)
 */
public List<ProtokollModel> getProtokollByAufgabenStatus(boolean ready) {
    // TODO Auto-generated method stub
    return null;
}

/*
 * (non-Javadoc)
 * 
 * @see util.ProtokollDAOService#getProtokollById(long)
 */
public ProtokollModel getProtokollById(long id) {
    try
    {
        entityFactory = Persistence
                .createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
        EntityManager em = entityFactory.createEntityManager();

        // Transaction starten
        em.getTransaction().begin();

        // Object aus der DB laden
        Query q = em.createQuery("select m from ProtokollModel m where m.id=:id");

        // Parameter setzen - siehe PreparedStatment
        q.setParameter("id", id);

        // liefert das Protokoll-Element zurück 
        ProtokollModel pm = (ProtokollModel) q.getSingleResult();

        // commit senden an die DB / Transaction abschliessen
        em.getTransaction().commit();

        // db connection schliessen
        em.close();

        return pm;
    }
    catch (Exception e)
    {
        Logger.console("Exception wurde ausgelösst! " + e);
        e.printStackTrace();
    } finally {

    }

    return null;
}

/*
 * (non-Javadoc)
 * 
 * @see util.ProtokollDAOService#getProtokollByProblem(java.lang.String)
 */
public List<ProtokollModel> getProtokollByProblem(String problem) {
    // TODO Auto-generated method stub
    return null;
}

/*
 * (non-Javadoc)
 * 
 * @see util.ProtokollDAOService#getProtokollByProblemStatus(boolean)
 */
public List<ProtokollModel> getProtokollByProblemStatus(boolean solved) {
    // TODO Auto-generated method stub
    return null;
}

/*
 * (non-Javadoc)
 * 
 * @see util.ProtokollDAOService#getProtokolls()
 */
public List<ProtokollModel> getProtokolls() {
    // TODO Auto-generated method stub
    return null;
}

/*
 * (non-Javadoc)
 * 
 * @see util.ProtokollDAOService#printTable()
 */
public void printTable() {
    // TODO Auto-generated method stub
}

}

person Marco    schedule 18.11.2009