Hibernate 在@Cache不工作的情况下休眠@Filter

Hibernate 在@Cache不工作的情况下休眠@Filter,hibernate,caching,spring-boot,filter,one-to-many,Hibernate,Caching,Spring Boot,Filter,One To Many,我有一个实体FormTable,它与另一个实体FormInLangagueTable有一对多关系,我想过滤掉语言内实体(基于动态参数),并返回最终对象,其中包含与过滤参数匹配的语言内对象列表 我通过@Filter和@FilterDef成功地实现了这一点,这两个工具都按预期工作,除了缓存没有出现,而且数据库在每个查询中都得到了命中 我发现,似乎我不是第一个有这个问题的人 我完全迷路了,在维护2级缓存的同时,如何根据动态参数过滤ForminLangTable列表 谢谢 表格: @Entity @Ta

我有一个实体FormTable,它与另一个实体FormInLangagueTable有一对多关系,我想过滤掉语言内实体(基于动态参数),并返回最终对象,其中包含与过滤参数匹配的语言内对象列表

我通过@Filter和@FilterDef成功地实现了这一点,这两个工具都按预期工作,除了缓存没有出现,而且数据库在每个查询中都得到了命中

我发现,似乎我不是第一个有这个问题的人

我完全迷路了,在维护2级缓存的同时,如何根据动态参数过滤ForminLangTable列表

谢谢

表格:

@Entity
@Table(name = "FORM")
@FilterDef(name = "userLanguageFilter", parameters = {
        // Set by the dao, to filter out irrelevant captions
        @ParamDef(name = "languageIdParam", type = "short")
})
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class FormTable {
    private Integer formId;

    ...

    /**
     * All the available language translations for the given form, won't be presented in the json response.
     */
    private List<FormInLanguageFactoryTable> formInLanguages;
    /**
     * Manually fetched from {@link #formInLanguages}, the language used
     * <b>specific to the user</b>, will be returned by the json.
     */
    private String specificLanguageCaption;

    @Id
    @Column(name = "_FormId")
    public Integer getFormId() {
        return formId;
    }

    public void setFormId(Integer formId) {
        this.formId = formId;
    }

    /**
     * Get all the form title in the corresponding languages, then filter it only to the current user language.
     * It <b>will not be presented in the final json,
     * but used in {@link #getSpecificLanguageCaption} to get the string, or null if none found.</b>
     */
    @OneToMany
    @JoinColumn(name = "_FormId", referencedColumnName = "_FormId")
    @Filter(name = "userLanguageFilter", condition = "_LanguageId = :languageIdParam")
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    @JsonIgnore
    public List<FormInLanguageTable> getFormInLanguages() {
        return formInLanguages;
    }

    public void setFormInLanguages(List<FormInLanguageTable> languageCaption) {
        this.formInLanguages = languageCaption;
    }

    /**
     * Will convert {@link #getFormInLanguages} into a string (the form caption, or null if none found)
     * @return
     */
    @Transient
    @JsonProperty("languageCaption")
    public String getSpecificLanguageCaption() {
        return this.getFormInLanguages().isEmpty() ? null : this.getFormInLanguages().get(0).getCaption();
    }
}
/**
 * The available languages for the given form
 */
@Entity
@Table(name = "FormInLanguage")
@Cache(usage= CacheConcurrencyStrategy.READ_ONLY)
public class FormInLanguageTable {
    private PK id;
    private String caption;

    @EmbeddedId
    @JsonIgnore
    public PK getId() {
        return id;
    }

    public void setId(PK id) {
        this.id = id;
    }

    @Column(name = "Caption")
    public String getCaption() {
        return caption;
    }

    public void setCaption(String caption) {
        this.caption = caption;
    }

    @Embeddable
    public static class PK implements Serializable {
        private Integer formId;
        private Short languageId;

        @Column(name = "_FormId")
        @JsonIgnore
        public Integer getFormId() {
            return formId;
        }

        public void setFormId(Integer formId) {
            this.formId = formId;
        }

        @Column(name = "_LanguageId")
        public Short getLanguageId() {
            return languageId;
        }

        public void setLanguageId(Short formFieldId) {
            this.languageId = formFieldId;
        }
    }
}
我也有同样的问题。 直到现在,我发现:

无法组合@Filter和@Cache集合 注释。这种限制是由于确保了一致性和一致性 因为过滤信息不存储在第二级 缓存

如果允许对当前筛选的集合进行缓存,则 二级缓存只存储整个集合的一个子集。 之后,每隔一个会话将从 缓存,即使会话级别筛选器未显式 激活

因此,第二级集合缓存仅限于 存储整个集合,而不是子集


我仍在寻找解决方案…

是的,我在发布问题后也发现了这一点,这是有意义的,使用过滤器创建数据的过滤版本,这意味着它必须存储整个数据集并每次应用过滤器,或者使用每个过滤器缓存数据集。两者都需要内存。我发现使用SpringBootCache注释来缓存服务方法更加有效(您还可以更好地控制缓存,也就是何时退出,为它注册了什么标识符等等)