Я написал EntityListener, используя «DescriptorEventAdapter» eclipseLink. Я попробовал почти все варианты, которые присутствуют в сети, но сущность, которую я сохраняю от своего слушателя, не сохраняется. Я подозреваю, что что-то подозрительное происходит с транзакцией, но не получило первопричины. Вот код:Объект не сохраняется в 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). Я не понимаю, почему?