【问题标题】:Why EclipseLink 's auto commit doesn't work with MySQL?为什么 EclipseLink 的自动提交不适用于 MySQL?
【发布时间】:2011-07-22 17:10:47
【问题描述】:

使用以下代码:

EntityManager manager = factory.createEntityManager();
manager.setFlushMode(FlushModeType.AUTO);
PhysicalCard card = new PhysicalCard();
card.setIdentifier("012345ABCDEF");
card.setStatus(CardStatusEnum.Assigned);

manager.persist(card);
manager.close();

当代码运行到这一行时,“卡片”记录不会出现在数据库中。但是,如果使用 FlushModeType.COMMIT,并使用这样的事务:

EntityManager manager = factory.createEntityManager();
manager.setFlushMode(FlushModeType.COMMIT);

manager.getTransaction().begin();
PhysicalCard card = new PhysicalCard();
card.setIdentifier("012345ABCDEF");
card.setStatus(CardStatusEnum.Assigned);

manager.persist(card);
manager.getTransaction().commit();

manager.close();

它工作正常。从 eclipselink 的日志中,我可以看到前面的代码没有发出 INSERT 语句,而第二个代码发出了。

我在这里错过了什么吗?我正在使用 EclipseLink 2.3 和 mysql 连接/J 5.1

【问题讨论】:

    标签: mysql jpa eclipselink


    【解决方案1】:

    我假设您在 Java SE 应用程序中使用 EclipseLink,或者在 Java EE 应用程序中使用应用程序管理的 EntityManager 而不是容器管理的 EntityManager。

    在这两种情况下,只有在与 EntityManager 关联的事务提交(使用 EntityTransaction.commit)或刷新 EntityManager 的持久性上下文时(使用 EntityManager.flush),才会刷新对持久性上下文所做的所有更新。这就是为什么第二个代码 sn-p 在调用 EntityTransactionbegincommit 方法时发出 INSERT,而第一个代码没有; em.persist 的调用不会发出 INSERT

    FlushModeType 值而言,the API documentation 声明如下:

    提交

    public static final FlushModeType COMMIT

    在事务提交时进行刷新。提供者可能会在 其他时候,但不是必须的。


    自动

    public static final FlushModeType AUTO

    (默认)在查询执行时进行刷新。

    由于在第一种情况下没有执行查询,因此不会发出与PhysicalCard 实体的持久性相对应的INSERT 语句。正是第二个中EntityTransaction 的显式提交导致发出INSERT 语句。

    【讨论】:

    • 感谢您的回答。但我还是不太明白。当我使用默认的 FlushModelType.Auto,并在persist() 之后发出flush() 时,flush 时发生异常,抱怨当前没有事务处于活动状态。
    • 我认为您将FlushModeType 与其他内容混淆了。它旨在定义 JPA 提供程序在必须执行查询时的刷新行为,以便查询的结果与对持久性上下文所做的任何更改保持一致。
    • 就抛出的异常而言,我并不感到惊讶。如果没有事务并且EntityManager.flush 需要事务来刷新持久性上下文中的更改,EntityManager.persist 将不执行任何操作。如果不使用EntityManager.getTransaction.begin() 启动事务,则没有与持久化上下文关联的事务,从而导致EntityManager.flush 上的错误。
    • 如果我必须进一步说明,事务通常与 Java EE 容器中的容器管理的 EntityManager 实例相关联。在 Java SE 应用程序中,您必须启动一个事务。此外,EntityManager.persist 仅用于将实体标记为稍后要持久化的托管实体。实际上是EntityManager.flushEntityTransaction.commit 向数据库发出INSERT 语句(见我的回答)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-31
    相关资源
    最近更新 更多