Я пытаюсь записать журнал аудита, используя прослушиватели событий Hibernate, такие как: PostInsertEventListener, PostUpdateEventListener и PostDeleteEventListener. Но у меня есть проблема, связанная с использованием entityManager для сброса данных из контекста постоянства в базу данных в следующих прослушивателях:
Вот исходный код:
EntityA.class
@Entity
@Table(name = "ENTITY_A")
public class EntityA implements Serializable {
private static final long serialVersionUID = -8674903027075338289L;
@Id
@Column(name = "ENTITY_A_ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
@SortableField
private Long buStepId;
@Column(name = "ENTITY_A_CODE", unique = true)
private String buStepCode;
@Column(name = "ENTITY_A_NAME")
private String buStepName;
@OneToMany(mappedBy = "buStep", fetch = FetchType.LAZY)
private List<BuEvent> BuEvents;
@OneToMany(mappedBy = "buStep", fetch = FetchType.LAZY)
private Set<BuEventFlow> BuEventFlows;
@ManyToOne
@JoinColumn(name = "GS_STATUS_ID", referencedColumnName = "STATUS_ID")
private RefStatus refGsStatus;
@ManyToOne
@JoinColumn(name = "GT_STATUS_ID", referencedColumnName = "STATUS_ID")
private RefStatus refGtStatus;
@ManyToOne
@JoinColumn(name = "GS_VERSION_ID", referencedColumnName = "VERSION_ID")
private RefVersion refGsVersion;
@ManyToOne
@JoinColumn(name = "GT_VERSION_ID", referencedColumnName = "VERSION_ID")
@AuditableField(name = "GT Version")
private RefVersion refGtVersion;
@ManyToOne
@JoinColumn(name = "EVO_TYPE_ID")
private RefEvoType refEvoType;
@Column(name = "TURN")
private Long turn;
@ManyToOne
@JoinColumn(name = "step_family_id", nullable = true)
private RefStepFamily buStepFamily;
@OneToMany(mappedBy = "buStep", fetch = FetchType.LAZY)
private List<BuStepFlow> buStepFlows;
@Transient
private Long stepFamilyId;
}
BusinessService.java
@Service
public class BusinessService {
@PersistenceContext
protected EntityManager entityManager;
public void createEntityA() {
EntityA entityA = createPojoEntityA();
entityManager.persist(entityA);
}
}
EntityEventListenerRegistry.java:
@Component
public class EntityEventListenerRegistry implements
PostInsertEventListener, PostUpdateEventListener,
PostDeleteEventListener {
@PersistenceContext
EntityManager entityManager;
@PostConstruct
protected void init() {
HibernateEntityManagerFactory hibernateEntityManagerFactory = (HibernateEntityManagerFactory) this.emf;
SessionFactoryImpl sessionFactoryImpl = (SessionFactoryImpl) hibernateEntityManagerFactory.getSessionFactory();
EventListenerRegistry registry = sessionFactoryImpl.getServiceRegistry().getService(EventListenerRegistry.class);
registry.appendListeners(EventType.POST_INSERT, this);
registry.appendListeners(EventType.POST_UPDATE, this);
registry.appendListeners(EventType.POST_DELETE, this);
}
@Override
public void onPostInsert(PostInsertEvent event) {
// Do something with entityA before
entityManager.flush();
// Do something with entityA after
}
...
}
Тогда исключение происходит в методе onPostInsert
:
org.hibernate.AssertionFailure: null id in EntityA entry (don't flush the Session after an exception occurs)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:60)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:175)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:135)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:216)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:85)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:38)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1300)
Мне потребовался один день для отладки, но я до сих пор не знаю причину почему. Не могли бы вы помочь мне объяснить это?