Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot 带eclipseLink事务问题的Spring引导_Spring Boot_Spring Data_Eclipselink_Auditing - Fatal编程技术网

Spring boot 带eclipseLink事务问题的Spring引导

Spring boot 带eclipseLink事务问题的Spring引导,spring-boot,spring-data,eclipselink,auditing,Spring Boot,Spring Data,Eclipselink,Auditing,我已经在eclipseLink中实现了EntityListener。我的应用程序是使用SpringBoot、SpringData和eclipseLink构建的。当数据插入1个表时,我需要在2个表(审计表)中插入记录。我的听众中有完整的管理器,一切似乎都正常工作。当我调试代码时,我可以看到我要保存的实体具有从序列生成的“id”,该序列保持在DB级别。但是当事务被提交时,我只看到主表数据,但审计表数据没有被提交。以下是示例代码: @Entity @Table(name="MyTable") @Ent

我已经在eclipseLink中实现了EntityListener。我的应用程序是使用SpringBoot、SpringData和eclipseLink构建的。当数据插入1个表时,我需要在2个表(审计表)中插入记录。我的听众中有完整的管理器,一切似乎都正常工作。当我调试代码时,我可以看到我要保存的实体具有从序列生成的“id”,该序列保持在DB级别。但是当事务被提交时,我只看到主表数据,但审计表数据没有被提交。以下是示例代码:

@Entity
@Table(name="MyTable")
@EntityListeners(MyTableListener.class)
public class MyTable implements Serializable{

    private static final long serialVersionUID = -5087505622449571373L;

    private Long id;
    // Rest of the fields

    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="MASTER_SEQ")
    @SequenceGenerator(name="MASTER_SEQ",sequenceName="MASTER_SEQ",allocationSize=1)
    public Long getId() {
        return id;
    }

    // Getters/Setters
}
侦听器代码:

 public class MyTableListener extends DescriptorEventAdapter {

        @Override
        public void postInsert(DescriptorEvent event) {
            MyTable msg = (MyTable)((InsertObjectQuery) event.getQuery()).getObject();
            EntityManager em = BeanUtil.getBean(EntityManager.class);
            MyAudit statusAudit = new MyAudit();
            statusAudit.setNewVal("NEW");
            statusAudit.setOldval(null);
            statusAudit.setTargetColumnName(targetColumn);
            statusAudit.setTargetRecordId(msg.getId());
            em.persist(statusAudit);
        }
    }
代码似乎没有问题。但是当我在集合中看到sql日志为“FINEST”时,我可以看到没有为审计表触发insert查询。
我已经处理这个问题两天多了,不知道到底是什么地方出了问题。请帮帮我。

您从未在
EntityManager
上调用
flush
。我怀疑发生了如下情况:

  • 可以通过Spring存储库将域实体添加到EntityManager

  • 某些东西触发了刷新,可能是Spring的事务处理

  • 您的域实体被刷新

  • 您的事件侦听器将被触发

  • 您将审计实体添加到EntityManager,但这些实体永远不会刷新

  • 数据库连接获得一个提交。保存除审计跟踪之外的所有内容

  • 如果这个理论是正确的,您应该能够通过日志和调试器验证它,那么您可能可以通过在侦听器中添加对
    flush
    的调用来修复它

    正如您在评论中所描述的,这会导致进一步的问题,发生这些问题是因为您试图做一些不应该做的事情

    根据,JPA规范不允许在回调事件中使用entitymanager

    通常,可移植应用程序的生命周期方法不应调用EntityManager或查询操作、访问其他实体实例或修改同一持久性上下文中的关系。生命周期回调方法可以修改调用它的实体的非关系状态


    看起来,就像我们被困在这里一样,所以你可能应该考虑一种完全不同的方法,比如 一些代码可能会有帮助。根据问题的当前状态,我们只能告诉您您的代码已损坏。同时,添加SQL和事务日志。代码已经添加。是的。您的理解是正确的,我的审计实体没有被刷新,我已经在sql日志中进行了验证。但我已经试过“同花顺”。如果我使用flush,我会得到“UniqueConstraintsViolation exception”,因为它会刷新所有内容,一旦spring提交了事务,它就会再次尝试保存“MyTable”数据,这会导致相同的实体被持久化。