Hibernate 在@Cache不工作的情况下休眠@Filter
我有一个实体FormTable,它与另一个实体FormInLangagueTable有一对多关系,我想过滤掉语言内实体(基于动态参数),并返回最终对象,其中包含与过滤参数匹配的语言内对象列表 我通过@Filter和@FilterDef成功地实现了这一点,这两个工具都按预期工作,除了缓存没有出现,而且数据库在每个查询中都得到了命中 我发现,似乎我不是第一个有这个问题的人 我完全迷路了,在维护2级缓存的同时,如何根据动态参数过滤ForminLangTable列表 谢谢 表格: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
@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注释来缓存服务方法更加有效(您还可以更好地控制缓存,也就是何时退出,为它注册了什么标识符等等)