2

我有一个每个子类一个表的设置。我有一个与 CarModelDesc 表映射的模型类。此表有 3 列:(modelDescId, makeId, model)

我们正在开发一个新的 i18n 系统,所以我制作了一个表 catalog_model_i18n ,它有 3 列(model_id, locale, model, display_name)。DisplayName 是新的,但 catalog_model_i18n.model 稍后将替换列 CarModelDesc .model。这些是我模型中的列定义:

@Id
@GeneratedValue
@Column(name = Cols.modelId)
private int modelId = -1;
@Column(name = Cols.makeId)
private Integer makeId = null;
@Column(name = Cols.model)
private String model = null;

@ElementCollection
@MapKeyClass(value = java.util.Locale.class)
@MapKeyColumn(name = "locale")
@CollectionTable(name = "catalog_model_i18n", joinColumns = @JoinColumn(name = "model_id"))
@Column(name = "model")
private Map<Locale, String> models = new HashMap<>();

@ElementCollection
@MapKeyClass(value = java.util.Locale.class)
@MapKeyColumn(name = "locale")
@CollectionTable(name = "catalog_model_i18n", joinColumns = @JoinColumn(name = "model_id"))
@Column(name = "display_name")
private Map<Locale, String> displayNames = new HashMap<>();

表 catalog_model_i18n 中的每一行都是一个翻译条目。主键基于model_is, locale组合。当我尝试将模型保存到数据库中时,休眠给了我一个Duplicate entry例外。

我启用了日志记录以查看正在执行的这些查询:

3 Query insert into sm360_webauto.CarModelDesc (makeId, model) values (45, 'modele fr')
3 Query insert into catalog_model_i18n (model_id, locale, display_name) values (884, 'fr', 'nom')
3 Query insert into catalog_model_i18n (model_id, locale, display_name) values (884, 'en', 'name')
3 Query insert into catalog_model_i18n (model_id, locale, model) values (884, 'fr', 'modele fr')
3 Query insert into catalog_model_i18n (model_id, locale, model) values (884, 'en', 'modele en')
3 Query rollback

我希望hibernate在这种情况下做的是插入一次,还是像这样更新:

3 Query insert into sm360_webauto.CarModelDesc (makeId, model) values (45, 'modele fr')
3 Query insert into catalog_model_i18n (model_id, locale, model, display_name) values (884, 'fr', 'modele fr', 'nom')
3 Query insert into catalog_model_i18n (model_id, locale, model,  display_name) values (884, 'en', 'modele en', 'name')

或者 :

3 Query insert into sm360_webauto.CarModelDesc (makeId, model) values (45, 'modele fr')
3 Query insert into catalog_model_i18n (model_id, locale, display_name) values (884, 'fr', 'nom')
3 Query insert into catalog_model_i18n (model_id, locale, display_name) values (884, 'en', 'name')
3 Query update catalog_model_i18n SET model_id=884 , locale='fr' , model='modele fr'
3 Query update catalog_model_i18n SET model_id=884 , locale='en' , model='modele en'

无论如何我可以告诉hibernate如何正确地做到这一点?可能无需将 SQL 代码写入我的模型。

谢谢

*更新:*

问题是休眠不知道我的模型类中的这两个变量链接到同一个表。因此,它执行了两个插入语句,但它是错误的。

到目前为止,此设置仍在工作,因为我每个 i18n 表只有一列,这从未引起问题。但是对于 2 列,hibernate 会执行两个插入请求并引发重复条目异常。我仍然没有解决方案。

4

1 回答 1

2

我相信应该有更好的方法来做到这一点,但由于 MySQL 支持NO DUPLICATE KEY,我们可以覆盖 Hibernate 完成的 SQL 插入来完成这项工作。这是我的模型中修改后的声明:

@SQLInsert(sql="INSERT INTO catalog_model_i18n(model_id, locale, name) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE name = VALUES(name)")
@ElementCollection
@MapKeyClass(value = java.util.Locale.class)
@MapKeyColumn(name = "locale")
@CollectionTable(name = "catalog_model_i18n", joinColumns = @JoinColumn(name = "model_id"))
@Column(name = "name")
private Map<Locale, String> names = new HashMap<>();

@SQLInsert(sql="INSERT INTO catalog_model_i18n (model_id, locale, display_name) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE display_name = VALUES(display_name)")
@ElementCollection
@MapKeyClass(value = java.util.Locale.class)
@MapKeyColumn(name = "locale")
@CollectionTable(name = "catalog_model_i18n", joinColumns = @JoinColumn(name = "model_id"))
@Column(name = "display_name")
private Map<Locale, String> displayNames = new HashMap<>();
于 2013-06-13T17:29:17.250 回答