2017-03-06 64 views
0

我已经在eclipseLink中实现了EntityListener。我的应用程序是使用spring-boot,spring-data和eclipseLink构建的。当插入1表中的数据时,我有要求在2个表(审计表)中插入记录。我的Listener中有EntityManager,一切似乎正常。当我调试代码时,我可以看到我将要保存的实体具有从在DB级维护的序列生成的“id”。但是当事务提交时,我只看到主表数据,但审计表数据没有被提交。下面是示例代码:eclipseLink事务问题的弹簧启动

@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”时,我可以看到插入查询未被审计表触发。 我一直在处理这个问题超过2天,不明白究竟是什么错误。请帮帮我。

+0

有些代码会有帮助。根据问题的当前状态,我们只能告诉您,您的代码已损坏。当你在它的时候,添加SQL和事务日志记录。 –

+0

已添加代码。 – rishi

回答

1

您从未在EntityManager上致电flush。我怀疑像下面这样的事情正在发生:

  1. 您可能通过Spring存储库将您的域实体添加到EntityManager。

  2. 某些东西会触发刷新,可能是Spring的事务处理。

  3. 您的域实体被刷新。

  4. 您的事件侦听器被触发。

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

  6. 数据库连接获取提交。保存所有内容,但不包括审计线索

如果这个理论正确IST,你应该能够通过日志和调试器来验证,你也许可以修复它,在你的听众增加flush通话。

正如你在评论中所描述的那样,这导致了进一步的问题,这是因为你正在尝试做一些你不应该做的事情。

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

一般而言,可移植应用程序的生命周期方法不应调用EntityManager或Query操作,访问其他实体实例或修改同一持久性上下文中的关系。生命周期回调方法可能会修改调用它的实体的非关系状态。

所以看起来,就像我们被卡在这里一样,所以你可能应该考虑一个完全不同的方法,如EclipseLink History tables

+0

是的。你的理解是正确的,我的审计实体没有被刷新,我已经在sql日志中验证过它。但我已经尝试过“冲洗”。如果我使用flush,我会得到“UniqueConstraintsViolation异常”,因为它会刷新所有内容,并且一旦事务在春天被提交时再次尝试保存导致相同实体持久化的“MyTable”数据。 – rishi

+0

更新了我的答案。 –