我目前正在研究一个我无法解释的错误,所以我在这里寻求帮助。
我正在使用Spring Data来获取我的对象,它们都由一个名为“FlagCMS”的列管理,如果设置为“S”,则意味着该对象不应该链接到任何其他新对象。这是一种软删除,到现在为止一直很好。
类定义如下(减去许多不相关的代码):
Action.java
@Entity
@Table(name = "action")
@Where(clause = FlagCMS.WHERE_NOSOFTDELETED)
@NamedEntityGraphs({
@NamedEntityGraph(name = "Action.maj", attributeNodes = {
@NamedAttributeNode("ouvragesAction")
}
})
public class Action {
@OneToMany(fetch = FetchType.LAZY, mappedBy = "action", cascade = CascadeType.ALL)
private Set<OuvrageAction> ouvragesAction = new HashSet<>();
@PreUpdate
protected void cascadeDelete() {
if (isDeleted()) {
getAllCascades().stream().filter(Objects::nonNull).forEach(SoftDeletable::setDeleted);
}
}
public Collection<OuvrageAction> getOuvragesAction() {
return ouvragesAction;
}
public void setOuvragesAction(final Set<OuvrageAction> ouvragesAction) {
this.ouvragesAction = ouvragesAction;
}
public List<Ouvrage> getOuvrages() {
return ouvragesAction.stream().map(OuvrageAction::get).collect(Collectors.toList());
}
}
OuvrageAction.java
@Entity
@Table(name = "ouvrage_action")
@Where(clause = FlagCMS.WHERE_NOSOFTDELETED)
@AttributeOverrides({
@AttributeOverride(name = "id", column = @Column(name = "id_action_ouvrage"))
})
public class OuvrageAction extends AbstractReferentielAction<Ouvrage> {
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "id_ouvrage", nullable = false)
private Ouvrage ouvrage;
public OuvrageAction() {
super();
}
public OuvrageAction(Ouvrage ouvrage, Action action) {
super(action);
this.ouvrage = ouvrage;
}
public Ouvrage getOuvrage() {
return ouvrage;
}
public void setOuvrage(Ouvrage ouvrage) {
this.ouvrage = ouvrage;
}
}
Ouvrage.java
@Entity
@Immutable
@Table(name = "ouvrage")
@Where(clause = FlagCMS.WHERE_NOSOFTDELETED)
public class Ouvrage {
@Column(name = "code")
protected String code;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
WHERE_NOSOFTDELETED
在FlagCMS.java中定义如下:
public static final String WHERE_NOSOFTDELETED = "(flag_cms = 'C' or flag_cms = 'M')";
我使用定义类似方法的两个不同的JpaRepositories访问Action对象,一个保持延迟加载,一个使用EntityGraph:
@EntityGraph(value = "Action.maj", type = EntityGraphType.LOAD)
List<Action> findDistinctByCodeIn(List<String> codes);
和
List<Action> findDistinctByCodeIn(List<String> codes);
现在假设我有Action
个对象链接到Ouvrage
个对象。第二个FlagCMS
设置为S
。使用惰性存储库,一切都很好,我得到了我的操作,并可以通过它访问code
的{{1}}属性。通过使用带有EntityGraph的存储库访问Action,我只得到一个EntityNotFoundException,告诉我Ouvrage
对象不存在。
这对我来说似乎不一致。
答案 0 :(得分:0)
如果有人遇到同样的问题,这就是诀窍:原来是@Where条件没有传播到通过链接表延迟加载的项目,但是它们在加载实体图形时会传播。
因此,如果您真的想要使用实体图,则必须从图中排除该特定属性,并在丢失事务之前手动加载所有这些属性。