use*_*038 11 java hibernate jpa internationalization
我正在尝试为java实体添加国际化(多语言)支持.在向每个新字段添加翻译时,我对所有选项都开放,尽可能少的样板代码.我不仅限于JPA,也可以使用hibernate注释.在最坏的情况下,普通sql也适合.可能有一些我没有找到的现成库.它不应该遵循我下面描述的想法.
理想情况下,我需要数据库看起来像这样:
i18n
+------+--------+------+
| id | locale | text |
+------+--------+------+
| 1 | en | foo |
+------+--------+------+
| 1 | de | bar |
+------+--------+------+
| 2 | en | foo2 |
+------+--------+------+
| 2 | de | bar2 |
+------+--------+------+
parent
+------+------+
| id | text |
+------+------+
| 99 | 1 |
+------+------+
| 100 | 2 |
+------+------+
Run Code Online (Sandbox Code Playgroud)
i18n
是应该只包含3列的表:id
,locale
和text
.表parent
有一列text
(如果只有单个字段需要i18n,否则需要更多列),其中包含来自的值i18n.id
.我在Parent类中尝试了以下映射:
@ElementCollection @CollectionTable(name="i18n", joinColumns = @JoinColumn(referencedColumnName="id"))
@MapKeyColumn(name="locale") @Column(name="text")
public Map<String, String> text = newHashMap();
Run Code Online (Sandbox Code Playgroud)
它似乎在禁用DDL生成时工作,我自己创建表,但是当启用DDL生成时,它会为它生成一个不必要的列i18n.parent_id
和约束:
ALTER TABLE PUBLIC.I18N ADD CONSTRAINT
PUBLIC.FK_HVGN9UJ4DJOFGLT8L78BYQ75I FOREIGN KEY(PARENT_ID) INDEX
PUBLIC.FK_HVGN9UJ4DJOFGLT8L78BYQ75I_INDEX_2 REFERENCES
PUBLIC.PARENT(ID) NOCHECK
Run Code Online (Sandbox Code Playgroud)
我怎样才能摆脱这个额外的列?是否可以避免从i18n
表到parent
表的引用?此链接使重用i18n
表很困难.我要么需要在i18n
表中保留一些鉴别器值,要么在整个数据库中使用GUID,因为不同表中的id会发生冲突.第一个选项意味着许多样板代码.第二个选项意味着在当前项目中要完成很多工作.
我需要一种可重用的方法来将i18n添加到实体中.我的父类看起来大致如此.并且将有几个这样的父类具有必须国际化的不同字段集.
@Entity
public class Parent {
@Id @GeneratedValue
public Long id;
public String title; // must be in internationalized
public String text; // must be in internationalized
public String details; // must be in internationalized
// ... other fields
}
Run Code Online (Sandbox Code Playgroud)
您不是只是@JoinColumn
通过使用错误地 指定了
@JoinColumn(referencedColumnName="id"))
Run Code Online (Sandbox Code Playgroud)
而不是
@JoinColumn(name="id"))
Run Code Online (Sandbox Code Playgroud)
http://docs.oracle.com/javaee/6/api/javax/persistence/JoinColumn.html#referencedColumnName()
当在 CollectionTable 映射中使用时,引用的列位于包含集合的实体的表中
因此,本质上您是在父级中(重新)定义 ID 列,而 Hibernate 使用其默认命名策略在 i18n 中生成 FK 列。
使用这个:
@Entity
@Table(name = "parent")
public class Parent {
@Id
private Long id;
@ElementCollection
@CollectionTable(name = "i18n", foreignKey = @ForeignKey(name = "ii8n_to_parent_fk"), joinColumns = @JoinColumn(name = "id"))
@MapKeyColumn(name = "locale")
@Column(name = "text")
public Map<String, String> text = new HashMap<>();
}
Run Code Online (Sandbox Code Playgroud)
生成以下内容:
19:29:08.890 [main] DEBUG jdbc.sqlonly - org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:51)
3. create table i18n (id bigint not null, text varchar(255), locale varchar(255) not null, primary
key (id, locale))
19:29:09.464 [main] DEBUG jdbc.sqlonly - org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:51)
3. alter table i18n add constraint ii8n_to_parent_fk foreign key (id) references parent
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3686 次 |
最近记录: |