我一直在尝试调试此问题。我的目标是尝试从hibernate拦截器中保存审计。我正在使用spring boot(1.5.3)和hibernate 5.0.12
以下是来自sql
的hibernate sql日志休眠:选择nextval(' user_sequence')
Hibernate:插入用户(creation_time,deleted,description,modifiedby,modified_time,name,email,enabled,password,phone_num,role_id,gid)值(?,?,?,?,?,?,?,? ,?,?,?,?)
休眠:选择nextval(' audit_sequence')
POST FLUSH DONE
如您所见,它获取审计对象的nextval,但未插入值。
public void postFlush(@SuppressWarnings("rawtypes") Iterator iterator) throws CallbackException {
try {
AuditRepository auditRepo =(AuditRepository)ApplicationContextProvider.getApplicationContext().getBean("auditRepository");
synchronized(audits) {
for (Long id:audits.keySet()) {
auditRepo.save(audits.get(id));
}
}
} catch (Exception e) {
logger.error(e.toString(),e.toString());
} finally {
synchronized (audits) {
audits.clear();
}
}
System.out.println("POST FLUSH DONE");
}
答案 0 :(得分:0)
我希望这能帮到你,这就是我为我的应用程序做的(Hibernate 5.2.6):
import java.io.Serializable;
import java.util.Date;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.EmptyInterceptor;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.type.Type;
import com.demo.domain.AuditLog;
import com.demo.util.GlobUtil;
public class CustomInterceptor extends EmptyInterceptor
{
private static final Logger log = LogManager.getLogger(CustomInterceptor.class);
public static final String OPERATION_TYPE_INSERT = "INSERT";
public static final String OPERATION_TYPE_UPDATE = "UPDATE";
public static final String OPERATION_TYPE_DELETE = "DELETE";
public static final String OPERATION_TYPE_SELECT = "SELECT";
// delete
public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
{
auditTrail(entity, id, null, state, propertyNames, types, OPERATION_TYPE_DELETE);
}
// update
public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState,
String[] propertyNames, Type[] types)
{
return auditTrail(entity, id, currentState, previousState, propertyNames, types, OPERATION_TYPE_UPDATE);
}
// select
public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
{
// return auditTrail(entity, id, null, state, propertyNames, types, OPERATION_TYPE_SELECT);
return true;
}
// insert
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
{
return auditTrail(entity, id, state, null, propertyNames, types, OPERATION_TYPE_INSERT);
}
private boolean auditable(Object entity)
{
return (entity instanceof Auditable);
}
private boolean auditTrail(Object entity, Serializable id, Object[] currentState, Object[] previousState,
String[] propertyNames, Type[] types, String operationType)
{
String prev = "";
String curr = "";
Session session = HibernateUtil.getSessionFactory().openSession();
if (!auditable(entity))
{
return false;
}
try
{
for (int index = 0; index < propertyNames.length; index++)
{
if (previousState != null)
{
prev = (previousState[index] == null) ? "" : previousState[index].toString();
}
if (currentState != null)
{
curr = (currentState[index] == null) ? "" : currentState[index].toString();
}
AuditLog auditLog = new AuditLog(id.toString(), entity.getClass().toString(),
propertyNames[index], prev, curr, operationType, GlobUtil.getUserName(), new Date());
session.beginTransaction();
session.save(auditLog);
session.getTransaction().commit();
}
}
catch (HibernateException e)
{
session.getTransaction().rollback();
log.error("Unable to process audit log for " + operationType + " operation", e);
}
finally
{
session.close();
}
return true;
}
}
当然,在xml或java中声明CustomInterceptor
。
<property name="entityInterceptor">
<bean class="com.demo.common.CustomInterceptor"/>
</property>
答案 1 :(得分:0)
我解决了这个问题。我按照EntityManager.persist() doesn't insert data when using @Transactional
中的建议更改了代码@Override
public void postFlush(@SuppressWarnings("rawtypes") Iterator iterator) throws CallbackException {
try {
AuditService service = (AuditService)ApplicationContextProvider.getApplicationContext().getBean("audit");
synchronized(audits) {
for (Long id:audits.keySet()) {
service.add(audits.get(id));
}
}
} catch (Exception e) {
logger.error(e.toString(),e.toString());
} finally {
synchronized (audits) {
audits.clear();
}
}
}
@Service("audit")
public class AuditServiceImpl implements AuditService {
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager em;
public Audit add(Audit obj) {
em.persist(obj);
return obj;
}
}