Hibernate使用相同的PK插入两次

时间:2013-06-07 16:33:27

标签: java mysql hibernate duplicates

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

我们正在开发一个新的i18n系统,所以我创建了一个包含3列(model_id, locale, model, display_name)的表catalog_model_i18n。 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代码写入我的模型。

由于

* 更新:*

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

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

1 个答案:

答案 0 :(得分: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<>();