Spring Data仅使用EntityGraph抛出EntityNotFoundException

时间:2018-01-12 16:23:35

标签: java spring hibernate jpa spring-data

我目前正在研究一个我无法解释的错误,所以我在这里寻求帮助。

我正在使用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对象不存在。

这对我来说似乎不一致。

1 个答案:

答案 0 :(得分:0)

如果有人遇到同样的问题,这就是诀窍:原来是@Where条件没有传播到通过链接表延迟加载的项目,但是它们在加载实体图形时会传播。

因此,如果您真的想要使用实体图,则必须从图中排除该特定属性,并在丢失事务之前手动加载所有这些属性。