jpa в настольном приложении SWING

Я разрабатываю настольное приложение для монофонических пользователей с использованием SWING. У меня был небольшой опыт работы с такими приложениями, в которых я использовал api java.sql и понял, что это совсем не удобно ...

В моем новом приложении я впервые пытаюсь использовать JPA, я прочитал много руководств, которые помогли мне понять почти все, что мне нужно, но не нашел хорошего примера для реальных настольных Java-приложений.

Я подумываю использовать следующую архитектуру, но не знаю, прав ли я ...

я думаю о создании класса MyPersistenceUnit:

    public class MyPersistenceUnit {
        private static EntityManagerFactory factory;
        private static EntityManager entityManager;

        public static void initiate(){
            factory=Persistence.createEntityManagerFactory("PU_Name");
            entityManager=factory.createEntityManager();
        }

        public static EntityManager getEntityManager() {
            return entityManager;
        }

        public static void close(){
            entityManager.close();
            factory.close();
        }

    }

метод initiate () будет вызван первым, а метод close () будет вызываться при закрытии приложения.

Пока приложение работает, все транзакции будут выполняться через экземпляр getEntityManager (), который доступен везде в приложении. Если я правильно понимаю приложения JSE, полученный диспетчер сущностей имеет расширенный контекст персистентности, который будет сохранять все сущности в управляемом состоянии, в то время как диспетчер сущностей не закрывается, и это заставило меня так думать ...

Я не знаю, упустил ли я что-то, поэтому я буду благодарен за любые чаевые

Обратите внимание, что я использую поставщика eclipselink со встроенной базой данных derby.
Спасибо


person George Casttrey    schedule 20.09.2011    source источник
comment
Я не понимаю, что этот вопрос имеет какое-либо отношение к Swing.   -  person Hovercraft Full Of Eels    schedule 21.09.2011
comment
извините за это, я удалил тег   -  person George Casttrey    schedule 21.09.2011


Ответы (4)


Насколько я понимаю, вопрос сводится к тому, следует ли вам открывать EntityManager и хранить его ссылку глобально и получать доступ к одному и тому же экземпляру повсюду в приложении.

Я думаю, что это нормально, если ваше приложение от маленького до среднего размера. Просто будьте осторожны, соединение с базой данных (следовательно, session / entityManager) может прерваться из-за различных факторов. И не делайте этого с транзакциями (т.е. не открывайте их в начале и не фиксируйте в конце). Делайте транзакции максимально детализированными.

Были различные обсуждения, в ходе которых более опытные люди обсуждали это, вы можете следить за этим здесь: для и counter по этому вопросу SO - Управление сеансом с использованием Hibernate в приложении Swing

Также см. это по той же теме.

Вот пример настольного приложения, созданного пользователем спящего режима. Это немного устарело, вы можете понять.

И, наконец, эта отличная статья для понимания общих концепций JPA для настольное приложение.

person kdabir    schedule 21.09.2011
comment
Думаю, я согласен с контраргументом, поскольку я считаю, что мое приложение немного больше среднего. Теперь проблема в том, что я знаком с EclipseLink и даже проверял тесты здесь показывает, что EclipseLink лучше, к сожалению, все статьи, решающие эту проблему, говорят о Hibernate. Что касается последней ссылки, которую вы дали, она просто показывает несколько очень простых примеров, так что на самом деле это не решает мою проблему. - person George Casttrey; 21.09.2011
comment
Я рад, что вы смогли сделать выбор, основываясь на этих ссылках. Если вы спросите мое личное мнение, я всегда отвечу: не оставляйте сессию / EM открытым надолго, всегда открывайте ее только тогда, когда это необходимо. Что касается Eclipselink, я сам никогда не использовал его ни в одном реальном проекте, поэтому я не могу это комментировать, но я надеюсь, что концептуально все не будет кардинально отличаться. - person kdabir; 21.09.2011
comment
В конце концов, я решил использовать long-life persistence-context, но со свойством eclipselink.persistence-context.reference-mode, установленным на «WEAK», который возьмет на себя ответственность за любые проблемы с управлением памятью. Я также установил элемент ‹shared-cache-mode› на «NONE», что отключит кеширование 2-го уровня, которое бесполезно в моем случае, и использую только кеш L1 (связанный с EM). Я думаю, что это наиболее логичное решение, поскольку создание нового EntityManager для каждой транзакции может быть дорогостоящим. Большое спасибо за помощь @kunal. - person George Casttrey; 26.09.2011
comment
@GeorgeCasttrey рад, что мой ответ помог. И спасибо, что написали, как вы это решили. Это, безусловно, поможет людям, ищущим по той же теме в будущем. - person kdabir; 26.09.2011

Переосмыслив свой дизайн, я решил изменить его следующим образом:

  • создать «постоянный» EM при запуске приложения и держать его открытым до завершения работы приложения. ПостоянныйEM ​​будет использоваться для поиска / обновления объектов, когда это необходимо (например, для получения ленивых отношений ...).
    Чтобы обеспечить эффективное управление памятью в СЛАБОМ режиме ссылок, я буду избегать постоянных ссылок Управляемые объекты constantEM.
  • создайте «временный» EM для загрузки «постоянных» данных, необходимых для запуска приложения. После загрузки данных закройте временный EM, чтобы отсоединить все данные, загруженные в память.
  • создать новый «временный» EM для каждой транзакции сохранения / слияния / удаления и закрыть его после фиксации транзакции.
person George Casttrey    schedule 09.11.2011
comment
просто примечание: я активно использую Eclipselink в течение года в производственной системе с очень похожей конструкцией. Хотя приложение на самом деле является фреймворком EE, мне пришлось перепрыгнуть через множество серверов приложений, и я управляю транзакциями самостоятельно. Eclipselink очень хорошо справляется с отсутствием тайм-аута, кешированием и просто работой. Если у вас есть отношения клиент-сервер к данным, то, что вы предложили, будет работать хорошо (кеш может не отражать состояние БД). Если вы не используете это, вы можете увидеть небольшой прирост производительности за счет кеширования. Удачи. - person Daniel B. Chapman; 09.11.2011

Поскольку это приложение SE, вы можете использовать встроенную базу данных. Я знаю, что H2 обычно разрешает посещение одного потока, поэтому, если вы находитесь в той же среде разработки и хотите избежать головной боли при управлении параллелизмом объекта.

Я предлагаю инкапсулировать вызов вашей службы в один поток и назначить этому потоку entitymanager.

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

в одном мире, я думаю, лучше поместить все сущности в один домен диспетчера сущностей и изолировать их от другого потока.

person Xiwen    schedule 22.06.2012

просматривали ли вы http://docs.jboss.org/hibernate/core/4.0/manual/en-US/html/transactions.html#transactions-basics-issues. Я думаю, что было бы разумно прочитать там документацию, прежде чем продолжать использовать объект сессий слишком долго. Я думаю, что лучший подход - использовать сеанс для выполнения простой единицы работы (например, операций CRUD).

Надеюсь, поможет!!.

Привет.

person Victor    schedule 28.12.2012