2017-02-17 65 views
0

我已经使用eclipseLink的“DescriptorEventAdapter”编写了EntityListener。我尝试了几乎所有在线的变体,但是我从听众保存的实体没有得到保存。我怀疑有些交易正在发生,但没有得到根本原因。下面是代码:实体没有在EclipseLink中保存EntityListener

package com.db; 

import java.util.Date; 
import javax.annotation.PostConstruct; 
import javax.persistence.EntityManagerFactory; 
import javax.transaction.Transactional; 
import javax.transaction.Transactional.TxType; 

import org.eclipse.persistence.descriptors.ClassDescriptor; 
import org.eclipse.persistence.descriptors.DescriptorEvent; 
import org.eclipse.persistence.descriptors.DescriptorEventAdapter; 
import org.eclipse.persistence.jpa.JpaEntityManager; 
import org.eclipse.persistence.queries.InsertObjectQuery; 
import org.eclipse.persistence.queries.UpdateObjectQuery; 
import org.eclipse.persistence.sessions.changesets.DirectToFieldChangeRecord; 
import org.eclipse.persistence.sessions.changesets.ObjectChangeSet; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.stereotype.Component; 

@Component 
public class NotificationMessageListener extends DescriptorEventAdapter { 

    public static Logger logger = LoggerFactory.getLogger(NotificationMessageListener.class); 

    private static final String targetColumn = "STATUS"; 

    //private static AuditRepository auditRepo; 

    @Autowired 
    private StatusAuditRepository statusAuditRepo; 

    @Autowired 
    private RuleResultAuditRepository ruleResultRepo; 

    @Autowired 
    private EntityManagerFactory factory; 

    JpaEntityManager entityManager = null; 

    @PostConstruct 
    public void init() { 

     try { 
      entityManager = (JpaEntityManager) factory.createEntityManager(); 
      // Use the entity manager to get a ClassDescriptor for the Entity class 
      ClassDescriptor desc = 
       entityManager.getSession().getClassDescriptor(NotificationMessage.class); 
      // Add this class as a listener to the class descriptor 
      desc.getEventManager().addListener(this); 
     } finally { 
      if (entityManager != null) { 
       // Cleanup the entity manager 
       entityManager.close(); 
      } 
     } 
    } 

    /*@Autowired 
    public void setAuditRepo(AuditRepository auditRepo) { 
     NotificationMessageListener.auditRepo = auditRepo; 
    }*/ 

    @Transactional(value = TxType.REQUIRES_NEW) 
    @Override 
    public void postInsert(DescriptorEvent event) { 
     logger.info("post insert is called "); 
     //NotificationMessage notificationMsg = (NotificationMessage) ((InsertObjectQuery) event.getQuery()).getObject(); 
     //entityManager.getTransaction().begin(); 
     NotificationStatusAudit statusAudit = new NotificationStatusAudit(); 
     statusAudit.setInsertionTime(new Date()); 
     //statusAudit.setNewVal(notificationMsg.getStatus()); 
     statusAudit.setNewVal("abc"); 
     statusAudit.setOldval("asdf"); 
     statusAudit.setTargetColumnName("from listner"); 
     //statusAudit.setTargetRecordId(notificationMsg.getId()); 
     statusAudit.setTargetRecordId(123L); 
     statusAudit = statusAuditRepo.save(statusAudit); 
     //entityManager.getTransaction().commit(); 
     //logger.info("Number of records "+statusAuditRepo.count()); 
     //auditRuleResult(notificationMsg.getMessageCorrelationId() , true); 
    } 

    @Override 
    public void postUpdate(DescriptorEvent event) { 
      ObjectChangeSet objectChanges = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet(); 
      DirectToFieldChangeRecord statusChanges = (DirectToFieldChangeRecord) objectChanges 
        .getChangesForAttributeNamed("status"); 
      if (statusChanges != null && !statusChanges.getNewValue().equals(statusChanges.getOldValue())) { 
       NotificationStatusAudit statusAudit = new NotificationStatusAudit(); 
       statusAudit.setInsertionTime(new Date()); 
       statusAudit.setNewVal("abc"); 
       statusAudit.setOldval("asdf"); 
       statusAudit.setTargetColumnName(targetColumn); 
       statusAudit.setTargetRecordId((Long) objectChanges.getId()); 
       statusAudit = statusAuditRepo.save(statusAudit); 
     } 
    } 
} 

这里,所有我需要做的就是保存记录在另一个(审核)表时,数据在一个表中获取插入。我的应用程序是春季启动应用程序,并使用eclipseLink进行持久化。我不得不在“PostConstruct”中手动注册我的实体侦听器,因为如果它是使用@EntityListner注释进行注册的,那么spring-data-repos没有自动装配。这里是我的问题:

1)对我的需求使用EntityListener是好方法还是应该使用直接“保存”操作? 2)我调试了EntityListener代码,并且即使在添加Requires_new之后方法也没有启动新的事务。我可以看到方法不被称为$ proxy(spring-proxy)。我不明白为什么?

回答

0

我不确定你在@PostConstruct init()方法中做了什么......但我怀疑你应该使用EclipseLink的DescriptorCustomizer配置这个DescriptorEventAdapter。这里是一个例子:

public class MessageEventListener extends DescriptorEventAdapter implements DescriptorCustomizer { 

    @Override 
    public void customize(ClassDescriptor descriptor) { 
     descriptor.getEventManager().addListener(this); 
    } 

    @Override 
    public void postUpdate(DescriptorEvent event) { 
     ObjectChangeSet objectChanges = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet(); 
     //More business logic... 
    } 
} 

@Entity 
@Customizer(MessageEventListener.class) 
public class Message { 
    @Id private long id; 
    private String content; 
} 
相关问题