如何在会话缓存中跨实体与 JPA 保持数据同步?
How to keep data in sync with JPA across entities in session cache?
我正在研究如何使会话缓存中的数据保持同步。我有以下示例:
@Table (name = "language")
@Entity
public class Language
{
@Id
@Column (name = "key", unique = true, nullable = false)
private String key;
@Column (name = "name", unique = true, nullable = false)
private String name;
@OneToMany (mappedBy = "language", cascade = { CascadeType.DETACH, CascadeType.REFRESH, CascadeType.REMOVE })
private Set<Translation> translations;
}
@Table (name = "translation")
@Entity
public class Translation
{
@Id
@GeneratedValue (strategy = GenerationType.SEQUENCE)
private Long id;
@ManyToOne(optional = false)
private Language language;
@ManyToOne (optional = false)
@JoinColumn(referencedColumnName = "key")
private TranslatableEntity translatable;
@Column(name = "value")
private String value;
}
@Table (name = "translatable")
@Entity
public class Translatable
{
@Id
@GeneratedValue (strategy = GenerationType.SEQUENCE)
private Long id;
@NotNull
@Size (max = 255)
@Column (name = "key", unique = true, nullable = false)
private String key;
@OneToMany (mappedBy = "translatable", cascade = { CascadeType.DETACH, CascadeType.REFRESH, CascadeType.REMOVE, CascadeType.PERSIST })
@MapKey (name = "language")
private Map<Language, Translation> translations;
}
基本上我是这样的:
// Print current translations for en language
Language language = languageRepository.getOne("en");
printTranslations(language);
// Add new translatable object with translation for english language
Translatable translatable = new Translatable();
translatable.addTranslation("en", "...")
translatableRepository.saveAndFlush(translatable)
// Again print translations for en language
// This still prints outdated information
language = languageRepository.getOne("en");
printTranslations(language);
所以我的问题是如何保持数据的一致性。
当 inserting/removing 一个带有一些翻译的新翻译时,语言实例中的翻译列表不会在会话缓存中更新。
我找不到任何满意的答案。这个最接近:.
谢谢
JPA 不会为您维护双向关系的两端。
一级缓存的目的是在事务实体中只加载一次。
这为您提供了解决问题的两种选择:
自己维护关系的两边,例如通过实现Translatable.add
方法来更新Language.translations
和Translation.language
通过在调用 languageRepository.getOne("en")
之前驱逐它或关闭会话(即事务)来强制重新加载 language
我正在研究如何使会话缓存中的数据保持同步。我有以下示例:
@Table (name = "language")
@Entity
public class Language
{
@Id
@Column (name = "key", unique = true, nullable = false)
private String key;
@Column (name = "name", unique = true, nullable = false)
private String name;
@OneToMany (mappedBy = "language", cascade = { CascadeType.DETACH, CascadeType.REFRESH, CascadeType.REMOVE })
private Set<Translation> translations;
}
@Table (name = "translation")
@Entity
public class Translation
{
@Id
@GeneratedValue (strategy = GenerationType.SEQUENCE)
private Long id;
@ManyToOne(optional = false)
private Language language;
@ManyToOne (optional = false)
@JoinColumn(referencedColumnName = "key")
private TranslatableEntity translatable;
@Column(name = "value")
private String value;
}
@Table (name = "translatable")
@Entity
public class Translatable
{
@Id
@GeneratedValue (strategy = GenerationType.SEQUENCE)
private Long id;
@NotNull
@Size (max = 255)
@Column (name = "key", unique = true, nullable = false)
private String key;
@OneToMany (mappedBy = "translatable", cascade = { CascadeType.DETACH, CascadeType.REFRESH, CascadeType.REMOVE, CascadeType.PERSIST })
@MapKey (name = "language")
private Map<Language, Translation> translations;
}
基本上我是这样的:
// Print current translations for en language
Language language = languageRepository.getOne("en");
printTranslations(language);
// Add new translatable object with translation for english language
Translatable translatable = new Translatable();
translatable.addTranslation("en", "...")
translatableRepository.saveAndFlush(translatable)
// Again print translations for en language
// This still prints outdated information
language = languageRepository.getOne("en");
printTranslations(language);
所以我的问题是如何保持数据的一致性。
当 inserting/removing 一个带有一些翻译的新翻译时,语言实例中的翻译列表不会在会话缓存中更新。
我找不到任何满意的答案。这个最接近:
谢谢
JPA 不会为您维护双向关系的两端。 一级缓存的目的是在事务实体中只加载一次。
这为您提供了解决问题的两种选择:
自己维护关系的两边,例如通过实现
Translatable.add
方法来更新Language.translations
和Translation.language
通过在调用
languageRepository.getOne("en")
之前驱逐它或关闭会话(即事务)来强制重新加载
language