【发布时间】:2020-01-29 22:15:28
【问题描述】:
我正在使用 Java 设计一个多语言系统,在我研究寻找存储多本地化文本的最佳数据库模型的过程中,我偶然发现了 Vertabelo 的博客和这个精彩的设计,from here:
但是,由于项目中有很多对象需要本地化,所以我避免自己编写所有的 Dao,如果可能的话,坚持使用 JPA。
问题是我对 JPA 了解不多,所以我搜索了这个问题的可用解决方案,并找到了另一篇很棒的博客文章(幸运的是,它解决了 Vertabelo 博客中显示的相同设计:https://thoughts-on-java.org/localized-data-hibernate/)
@Entity
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
public class LocalizedProduct {
@EmbeddedId
private LocalizedId localizedId;
@ManyToOne
@MapsId("id")
@JoinColumn(name = "id")
private Product product;
private String name;
private String description;
...
}
@Embeddable
public class LocalizedId implements Serializable {
private static final long serialVersionUID = 1089196571270403924L;
private Long id;
private String locale;
public LocalizedId() {
}
public LocalizedId(String locale) {
this.locale = locale;
}
// getter and setter methods ...
{
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
@Version
private int version;
@ManyToOne(fetch = FetchType.LAZY)
private Supplier supplier;
private Double price;
@OneToMany(mappedBy = "product", cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, orphanRemoval = true)
@MapKey(name = "localizedId.locale")
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
private Map<String, LocalizedProduct> localizations = new HashMap<>();
...
public String getName(String locale) {
return localizations.get(locale).getName();
}
public String getDescription(String locale) {
return localizations.get(locale).getDescription();
}
}
Product p = new Product();
p.setPrice(19.99D);
LocalizedProduct lpDe = new LocalizedProduct();
lpDe.setId(new LocalizedId("de"));
lpDe.setProduct(p);
lpDe.setName("Hibernate Tips - Mehr als 70 Lösungen für typische Hibernateprobleme");
p.getLocalizations().put("de", lpDe);
LocalizedProduct lpEn = new LocalizedProduct();
lpEn.setId(new LocalizedId("en"));
lpEn.setProduct(p);
lpEn.setName("Hibernate Tips - More than 70 solution to common Hibernate problems");
p.getLocalizations().put("en", lpEn);
em.persist(p);
接下来就是我要解决的问题了。
“thoughts-on java”中提出的解决方案检索一个对象,该对象包含一个地图,其中包含来自所有语言的所有翻译,并且这种行为是不希望的,因为我的系统将以至少 104 种语言呈现数据,最终。
问题是: 有没有办法调整这个解决方案,以便能够查询传递实体 id 和区域设置 id 的对象,并一次将翻译的对象翻译成一种语言?
【问题讨论】: