简体   繁体   English

如何让 Hibernate Interceptor 获取某些超类字段?

[英]How do I get a Hibernate Interceptor to pick up certain superclass fields?

I have some entities.我有一些实体。 For example例如

@Entity
@IdClass(SecurityUserPublisherId.class)
@Table(name="SECUSERPUB")
public class SecurityUserPublisher extends Auditable {
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name="USERPUB_CONTACTID", updatable=false, nullable=false)
    protected Integer contactId = null;
    @Id
    @Column(name="USERPUB_PUBID", updatable=false, nullable=false)
    protected Integer publisherId = null;

    public SecurityUserPublisher() {
        super();
        setAudited(true);
    }

    public SecurityUserPublisher(SecurityUserPublisher securityUserPublisher) {
        setContactId(securityUserPublisher.getContactId());
        setPublisherId(securityUserPublisher.getPublisherId());
    }

    public Integer getContactId() {return contactId;}

    public void setContactId(Integer contactId) {this.contactId = contactId;}

    public Integer getPublisherId() {return publisherId;}

    public void setPublisherId(Integer publisherId) {this.publisherId = publisherId;}

    @Transient
    @Override
    public String getPrimaryKeyDisplay() {
        StringBuilder sb = new StringBuilder();
        if (contactId == null) {
            sb.append(" contactId: null");
        } else {
            sb.append(" contactId: " + contactId.toString());
        }
        if (publisherId == null) {
            sb.append(" publisherId: null");
        } else {
            sb.append(" publisherId: " + publisherId.toString());
        }
        return sb.toString();
    }

    @Transient
    @Override
    public String getAuditDetail() {
        return new ToStringBuilder(this).append("contactId", contactId).append("publisherId", publisherId).toString();
    }
}

They extend the Auditable class他们扩展了 Auditable 类

public abstract class Auditable implements Serializable {
    private static final long serialVersionUID = 1L;
    protected Integer auditContactId = null;
    protected Boolean audited = false;

    public void setAuditContactId(Integer auditContactId) {this.auditContactId = auditContactId;}
    public Integer getAuditContactId() {return auditContactId;}
    public Boolean isAudited() {return audited;}
    protected void setAudited(Boolean audited) {this.audited = audited;}
    public abstract String getPrimaryKeyDisplay();
    public abstract String getAuditDetail();
}

And I have an interceptor我有一个拦截器

public class AuditInterceptor extends EmptyInterceptor {
    private static final long serialVersionUID = 1L;

    private Set<Auditable> inserts = new HashSet<>();
    private Set<Auditable> updates = new HashSet<>();
    private Set<Auditable> deletes = new HashSet<>();

    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
        throws CallbackException {

        if (entity != null && entity instanceof Auditable && ((Auditable)entity).isAudited()){
            System.out.println(entity.toString());
            System.out.println(id.toString());
            System.out.println(Arrays.toString(state));
            System.out.println(Arrays.toString(propertyNames));
            System.out.println(Arrays.toString(types));
            inserts.add((Auditable)entity);
        }
        return super.onSave(entity, id, state, propertyNames, types);

    }

    @Override
    public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types)
        throws CallbackException {

        if (entity instanceof Auditable && ((Auditable)entity).isAudited()){
            updates.add((Auditable)entity);
        }
        return super.onFlushDirty(entity, id, currentState, previousState, propertyNames, types);

    }

    @Override
    public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {

        if (entity instanceof Auditable && ((Auditable)entity).isAudited()){
            System.out.println(entity.toString());
            System.out.println(id.toString());
            System.out.println(Arrays.toString(state));
            System.out.println(Arrays.toString(propertyNames));
            System.out.println(Arrays.toString(types));
            deletes.add((Auditable)entity);
        }
    }

    //called before commit into database
    @Override
    public void preFlush(@SuppressWarnings("rawtypes") Iterator iterator) {
    }

    //called after committed into database
    @Override
    public void postFlush(@SuppressWarnings("rawtypes") Iterator iterator) {
        try {
            for (Iterator<Auditable> iter = inserts.iterator(); iter.hasNext();) {
                Auditable entity = iter.next();
                iter.remove();
                logIt("Saved", entity);
            }

            for (Iterator<Auditable> iter = updates.iterator(); iter.hasNext();) {
                Auditable entity = iter.next();
                iter.remove();
                logIt("Updated", entity);
            }

            for (Iterator<Auditable> iter = deletes.iterator(); iter.hasNext();) {
                Auditable entity = iter.next();
                iter.remove();
                logIt("Deleted", entity);
            }

        } finally {
            inserts.clear();
            updates.clear();
            deletes.clear();
        }
    }

    public void logIt(String action, Auditable entity) {
        if (!entity.isAudited()) {
            return;
        }
        Session tempSession = SessionHelper.getSession().getSession().getSessionFactory().openSession();
        Audit auditRecord = new Audit();
        auditRecord.setAction(action);
        auditRecord.setContactId(entity.getAuditContactId());
        auditRecord.setDetail(entity.getAuditDetail()); 
        auditRecord.setCreatedTimestamp(new Timestamp(System.currentTimeMillis())); 
        auditRecord.setEntityPK(entity.getPrimaryKeyDisplay()); 
        auditRecord.setEntityName(entity.getClass().toString());
        tempSession.save(auditRecord);
        tempSession.flush();
    }

}

I can create entities我可以创建实体

final SecurityUserPublisher secUserPub = new SecurityUserPublisher();
secUserPub.setContactId(currentUser.getContactId());
secUserPub.setPublisherId(publisher.getId());
secUserPub.setAuditContactId(parentFrame.getUser().getContactId());
try {
    SessionHelper.getCreate().createSecurityUserPublisher(secUserPub);

and the audit trail looks good AUDIT_ID 120385 AUDIT_ACTION Saved审计跟踪看起来不错 AUDIT_ID 120385 AUDIT_ACTION Saved
AUDIT_DETAIL SecurityUserPublisher@678541a[contactId=8721,publisherId=360] AUDIT_CREATEDTS 2019-04-04 13:52:57 AUDIT_ENTITYPK contactId: 8721 publisherId: 360 AUDIT_ENTITYNAME SecurityUserPublisher AUDIT_CONTACTID 7341 AUDIT_DETAIL SecurityUserPublisher@678541a[contactId=8721,publisherId=360] AUDIT_CREATEDTS 2019-04-04 13:52:57 AUDIT_ENTITYPK contactId:8721publisherId:360 AUDIT_ENTITYNAME AUDIT_ENTITYNAMEITCON34PublisherIDITCON34Publisher

But when I try to delete但是当我尝试删除时

final SecurityUserPublisher secUserPub = SessionHelper.getSession().getSecurityUserPublisher(currentUser.getContactId(), publisher.getId());
secUserPub.setAuditContactId(parentFrame.getUser().getContactId());
try {
    SessionHelper.getRemove().removeSecurityUserPublisher(secUserPub);

the audit trail contact id is null, even though I expressly set it before calling the remove.审计跟踪联系人 ID 为空,即使我在调用 remove 之前明确设置了它。 AUDIT_ID 120386 AUDIT_ACTION Deleted AUDIT_ID 120386 AUDIT_ACTION 已删除
AUDIT_DETAIL SecurityUserPublisher@1d184bc8[contactId=8721,publisherId=360] AUDIT_CREATEDTS 2019-04-04 13:53:35 AUDIT_ENTITYPK contactId: 8721 publisherId: 360 AUDIT_ENTITYNAME SecurityUserPublisher AUDIT_DETAIL SecurityUserPublisher@1d184bc8[contactId=8721,publisherId=360] AUDIT_CREATEDTS 2019-04-04 13:53:35 AUDIT_ENTITYPK contactId: 8721publisherId: 360 AUDIT_ENTITYNAME SecurityUser
AUDIT_CONTACTID null AUDIT_CONTACTID 空

So, how do I get the onDelete to show the contactId in the Audit table?那么,如何让 onDelete 在审计表中显示 contactId 呢?

Use @MappedSuperclass annotation on Auditable class.在 Auditable 类上使用@MappedSuperclass注释。 Otherwise Hibernate ignores super class fields and fields of Auditable class are not saved into DB.否则 Hibernate 会忽略超类字段,并且 Auditable 类的字段不会保存到 DB 中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM