【问题标题】:jpa on a Desktop SWING Application桌面 SWING 应用程序上的 jpa
【发布时间】:2011-11-21 10:46:29
【问题描述】:

我正在使用 SWING 开发单用户桌面应用程序。我对这种使用 java.sql api 的应用程序有一点经验,并发现它根本不舒适......

在我的新应用程序中,我第一次尝试使用 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();
        }

    }

initial() 方法将首先被调用,而 close() 方法将在应用程序关闭时被调用。

当应用程序运行时,所有事务都将通过 getEntityManager() 实例完成,该实例可在应用程序的任何位置访问。如果我对 JSE 应用程序的理解是正确的,则获得的实体管理器具有扩展的持久性上下文,它将使所有实体保持在托管状态,而实体管理器不会关闭,这就是让我这样想的原因 ...

我不知道我是否遗漏了什么,所以任何提示将不胜感激

请注意,我将 eclipselink 提供程序与 derby 嵌入式数据库一起使用。
谢谢

【问题讨论】:

  • 看不出这个问题和Swing有什么关系。
  • 抱歉,我已经删除了标签

标签: java jpa desktop-application eclipselink


【解决方案1】:

据我了解,问题归结为您是否应该打开 EntityManager 并全局存储其引用并在应用程序的任何地方访问相同的实例。

我认为如果您的应用程序是中小型应用程序,那应该没问题。请注意数据库连接(因此 session/entityManager)可能由于各种因素而下降。并且不要对事务执行此操作(即不要在开始时打开它们并最终提交)。尽可能细化交易。

已经有各种讨论,更有经验的人对此进行了讨论,您可以在这里关注:forcounter 关于这个 SO 问题的论点 - Session management using Hibernate in a Swing application

另请参阅this,了解同一主题。

Here 是一个由 hibernate 提交者创建的示例桌面应用程序。有点老了,你可以理解。

最后,this 是了解桌面应用程序的一般 JPA 概念的好文章。

【讨论】:

  • 我想我会选择反驳论点,因为我认为我的应用程序比中型大一点。现在的问题是我对 EclipseLink 很熟悉,甚至我在here 中检查的测试表明 EclipseLink 更好,不幸的是所有解决问题的文章都在谈论 Hibernate。关于您提供的最后一个链接,它仅显示了一些非常基本的示例,因此并不能真正解决我的问题。
  • 很高兴您可以根据这些链接做出选择。如果您询问我的个人意见,我总是会说不要长时间打开会话/ EM,始终只在需要时打开它。关于 Eclipselink,我自己从未在任何实际项目中使用过它,所以我无法对此发表评论,但我希望在概念上不会有根本的不同。
  • 最后,我决定使用长寿命持久性上下文,但将 'eclipselink.persistence-context.reference-mode' 属性设置为 'WEAK' 将负责任何内存管理问题.我还将 元素设置为“NONE”,这将禁用在我的情况下无用的二级缓存,并且仅使用 L1 缓存(与 EM 相关)。我认为这是最合乎逻辑的解决方案,因为为每个事务创建一个新的 EntityManager 可能会很昂贵。非常感谢@kunal 的帮助。
  • @GeorgeCasttrrey 很高兴我的回复有所帮助。并感谢您发布您如何解决它。它肯定会帮助人们在未来搜索相同的主题。
【解决方案2】:

重新思考我的设计后,我决定将其更改如下:

  • 在应用程序启动时创建一个“永久”EM,并保持打开状态直到应用程序关闭。 PermanentEM 将用于在需要时查找/刷新实体(例如用于获取惰性关系...)。
    为了确保通过 WEAK 引用模式有效管理内存,我将避免永久引用 PermanentEM 的托管实体。
  • 创建一个“临时”EM 来加载启动应用程序所必需的“永久”数据。一旦加载的数据关闭该临时 EM,就可以分离所有加载到内存中的数据。
  • 为每个持久化/合并/删除事务创建一个新的“临时”EM,并在事务提交后关闭它。

【讨论】:

  • 请注意:一年来,我一直在使用非常相似的设计的生产系统上大量使用 Eclipselink。虽然该应用程序实际上是一个 EE 框架,但我不得不跳过各种应用程序服务器并自己管理事务。 Eclipselink 在不超时、缓存和“正常工作”方面做得非常好。如果您与数据有客户端-服务器关系,那么您建议的内容将运行良好(缓存可能无法反映数据库的状态)。如果您不使用它,您可能会看到缓存带来的小幅性能提升。祝你好运。
【解决方案3】:

由于它是一个 SE 应用程序,您可以使用嵌入式数据库。 我知道H2通常允许一个线程访问,所以如果你在同一个开发环境中,想避免实体的并发控制这个头疼的问题。

我的建议是将您的服务调用封装在一个线程中,并为该线程分配一个实体管理器。

不允许其他线程使用实体,然后定义数据访问接口,以适当的数据结构将数据从实体传输到其他对象。

在一个世界中,我认为最好将所有实体放在一个实体管理器域中并将它们与其他线程隔离。

【讨论】:

    【解决方案4】:

    你看过http://docs.jboss.org/hibernate/core/4.0/manual/en-US/html/transactions.html#transactions-basics-issues。我认为在继续使用会话对象之前阅读那里的文档是明智的。我想更好的方法是使用会话来做一个简单的工作单元(例如:CRUD 操作)。

    希望对你有帮助!!

    您好。

    【讨论】:

      猜你喜欢
      • 2013-01-02
      • 2013-05-17
      • 2011-01-19
      • 2012-12-12
      • 2010-11-15
      • 2011-04-10
      • 1970-01-01
      • 1970-01-01
      • 2012-05-22
      相关资源
      最近更新 更多