我对以下代码所看到的行为感到非常惊讶:
@Repository
@Transactional
public class SuiviDao {
public Suivi getSuivi(SuiviPK pk) {
final Suivi suivi = em.find(Suivi.class, pk);
assert em.contains(suivi);
// throws occasionally an assertion error
assert em.contains(suivi.getCommune());
return suivi;
}
}
我希望通过find
方法调用返回托管实体。
返回的suivi
始终如此。
但是,不会管理commune
实例。
这是正常的JPA行为吗?或者它是Hibernate特有的东西(我使用的是4.3.7版本)?
有一个简单的解决方法(见下文):
if (!em.contains(suivi.getCommune())) {
final Commune commune = em.find(Commune.class, suivi.getCommune().getId());
suivi.setCommune(commune);
}
通过进一步挖掘,我发现在返回非托管Commune实体的情况下,实体不是从DB加载,而是从Hibernate的会话缓存加载。
相关课程的相关部分:
@Entity
public class Suivi {
@EmbeddedId
private SuiviPK pk = new SuiviPK();
@MapsId("commune")
@ManyToOne
private Commune commune;
@MapsId("echeance")
@NotNull
@ManyToOne(cascade = { CascadeType.REFRESH })
private Echeance echeance;
// remaining of class body
}
@Embeddable
public class SuiviPK implements Serializable {
@Column(name = "ECHEANCE")
private Long echeance;
@Column(name = "COMMUNE")
private Long commune;
// remaining of class body
}