によって管理される次@Transactional
のメソッドがありますHibernateTransactionManager
。
@Transactional(rollbackFor = NoActiveTraceException.class)
public void insertTraceEvent(TraceEvent traceEvent) throws NoActiveTraceException {
Trace trace = traceDao.findActiveForNumber(traceEvent.getSourceParty());
if (trace == null) {
throw new NoActiveTraceException(traceEvent.getSourceParty()); // custom
} else {
traceEvent.setTrace(trace);
trace.getTraceEvents().add(traceEvent); // returns set to which I can add
// there is a Cascade.All on the @OneToMany set
traceDao.create(traceEvent);
}
}
// ...in traceDao
@Override
public Long create(TraceEvent traceEvent) {
getCurrentSession().persist(traceEvent);
return traceEvent.getTraceEventId();
}
Trace
TraceEvent
Hibernate によって管理されるエンティティです。
開発中にこのコードをテストしたとき、問題はまったくありませんでした。ただし、本番環境では、時々スローされます
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [myobject#2664]
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:180) ~[hibernate-core-4.1.9.Final.jar:4.1.9.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:136) ~[hibernate-core-4.1.9.Final.jar:4.1.9.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208) ~[hibernate-core-4.1.9.Final.jar:4.1.9.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151) ~[hibernate-core-4.1.9.Final.jar:4.1.9.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:78) ~[hibernate-core-4.1.9.Final.jar:4.1.9.Final]
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:843) ~[hibernate-core-4.1.9.Final.jar:4.1.9.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:818) ~[hibernate-core-4.1.9.Final.jar:4.1.9.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:822) ~[hibernate-core-4.1.9.Final.jar:4.1.9.Final]
at com.package.model.dao.impl.TraceDaoHibernateImpl.create(TraceDaoHibernateImpl.java:116) ~[TraceDaoHibernateImpl.class:na]
それを持続しようとするとき。これを引き起こすprodとdevの違いは考えられません。このプロシージャは、すべてから独立しています (トランザクション内で実行されます)。
.add(traceEvent)
を呼び出すと、PersistentSet
(およびpersist
traceEvent も) が汚れることを理解しています。そして、私が を呼び出すとcreate(traceEvent)
、それも試みてpersist
、Hibernate セッションに同じオブジェクトを追加することがあります。
例外が発生する理由と、このようにランダムな間隔で発生するのはなぜですか?
エンティティの編集
@Entity
@Table(name = "TRACE_EVENT")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class TraceEvent {
@Id
@GenericGenerator(name = "generator", strategy = "increment")
@GeneratedValue(generator = "generator")
@Column(name = "trace_event_id")
private Long traceEventId;
@Column(nullable = false)
private Calendar transmissionDate;
@Column(nullable = false)
private String sourceParty;
@Column
private String destinationParty;
@ManyToOne(optional = false)
@JoinColumn(name = "trace_id")
private Trace trace;
と
@Entity
@Table(name = "TRACE")
public class Trace {
@Id
@GenericGenerator(name = "generator", strategy = "increment")
@GeneratedValue(generator = "generator")
@Column(name = "trace_id")
private Long traceId;
@Column(nullable = false)
private String number;
@Column(nullable = false)
private Calendar startDate;
@Column
private Calendar endDate;
@Column(nullable = false)
private Boolean isActive = false; // default value of false
// USED TO BE CASCADE.ALL
@OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.REMOVE}, mappedBy = "trace")
private Set<TraceEvent> traceEvents = new HashSet<>();
@ManyToOne
private Account account;