Я проектирую мультиязычную систему, используя Java, и во время моих исследований, чтобы найти лучшую модель базы данных для хранения многоязычного текста, я наткнулся на блог Вертабело и этот замечательный дизайн, отсюда :
Модель базы данных
Однако, поскольку в проекте нужно локализовать множество объектов, я избегаю писать все дао и придерживаться JPA, если возможно.
Дело в том, что я еще не очень хорошо знаю JPA, поэтому я поискал доступные решения этой проблемы и нашел еще один отличный пост в блоге (который, к счастью, затрагивает тот же дизайн, что и в блоге Вертабело) здесь: 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);
Затем возникает проблема, которую я хочу решить.
Решение, представленное в «мыслях java», возвращает объект хранение карты со всеми переводами со всех языков, прикрепленных к ней, и такое поведение нежелательно, так как моя система в конечном итоге представит данные как минимум на 104 языках.
Вопрос в следующем: существует ли способ настроить это решение, чтобы иметь возможность запрашивать объект, передающий идентификатор сущности и идентификатор языкового стандарта, и одновременно получать переведенный объект на один язык?