@Entity
public class Language {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(length = 2)
private String code; //EN, DE, US
public Language(String code) {
this.code = code;
}
}
@Entity
public class ProductText {
@OneToOne(Cascade.ALL)
private Language lang;
}
ProductText text = new ProductText();
text.setLang(new Language("en")); //what if "en" exists?
dao.save(text);
现在,当我持久保存ProductText
时,每次都会生成一个新的Language
对象。
我是否可以阻止这种情况,如果存在code = 'en'
的语言表条目,则应该链接此现有实体。
我最初的目标是不必在产品文本表中多次重复countryCodeString“EN”,而只是引用id。但这真的有意义吗?我是否应该在没有额外表格的情况下使用普通String
? (我后来想查询productTexts where lang = 'de'
)列表。
之前执行像dao.findByLang("en")
这样的选择的唯一更改是?
或者是否还有一些hibernate功能可以支持这个而不需要自己显式执行查询?
答案 0 :(得分:1)
你处理价值" en"进一步还是直接显示?如果仅用于显示目的,我只会存储字符串,但如果您想通过使用外键ID减少冗余,则 创建包含语言字符串{{1}的Entity
这可以通过实体管理器持久存储,并且在持久重用之前必须从实体管理器中获取。
答案 1 :(得分:1)
如果该语言只有三种不同的可能值,您也可以使用这样的枚举:
public enum Language {
EN("EN"),
DE("DE"),
US("US");
private String code; //EN, DE, US
public Language(String code) {
this.code = code;
}
// Getter...
}
@Entity
public class ProductText {
@Enumerated(EnumType.STRING)
// Or @Enumerated(EnumType.ORDINAL)
private Language lang;
}
EnumType.STRING
将枚举作为String存储在数据库中,而EnumType.ORDINAL
将它存储为int。 Int可能更高效,但如果在枚举中插入新值,映射可能会更改。字符串更灵活,因为它将使用枚举成员的名称。
在这两种情况下,您不必管理单独的实体,并且hibernate不会创建额外的表,并且它比使用普通字符串更安全类型。
答案 2 :(得分:0)
如果Language中唯一的值是2或3个字母的字符串,为什么不将字符串作为成员呢?这将更快更有效。