I am trying to log any changes to my JPA entities. For this reason, each object inherits from an abstract entity class that has a list of LogEntry objects.
AbstractEntity class:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@EntityListeners(ChangeListener.class)
public abstract class AbstractEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Version
private Long version;
@Temporal(TemporalType.DATE)
private Date validFrom;
@Temporal(TemporalType.DATE)
private Date validTo;
private String name;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "abstractEntity")
private List<LogEntry> logEntry = new ArrayList<LogEntry>();
}
LogEntry Class:
@Entity
public class LogEntry extends AbstractEntity {
@ManyToOne
@JoinColumn
protected AbstractEntity abstractEntity;
@ManyToOne
@JoinColumn
protected Person person;
@Column(updatable=false, insertable=false, columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
protected Date changeDate;
protected String comment;
}
My approach was to create a new LogEntry object and add it to the LogEntry list of the object before the entity was updated or saved.
I tried the following solutions:
- Using callback annotations (@PreUpdate, @PrePersist, etc.) directly in an entity class or separated in an entity listener associated with AbstractEntity
- EclipsLink DescriptorEvent . . preUpdate LogEntry . LogEntry , preUpdate ( preUpdate), . , unitOfWork . ( ) , ?
, preUpdateWithChanges , , -, . .
(, validTo) . LogEntry , , LogEntry. bean jndi lookup LogEntry . jndi , bean .
:
public class ChangeListener extends DescriptorEventAdapter {
@Override
public void preUpdate(DescriptorEvent event) {
AbstractEntity entity = (AbstractEntity) event.getObject();
if (!(entity instanceof LogEntry)) {
LogEntry logEntry = new LogEntry();
logEntry.setPerson(getSessionController().getCurrentUser());
logEntry.setAbstractEntity(entity);
entity.getLogEntries().add(logEntry);
}
}
}
Hibernate Envers .
EclipseLink 2.3.2.