我有一个包含2个主要列的表:名称和名称没有重音。 当第一个更改时,我希望hibernate更新第二个:
@Column(name = "name")
public String getName() {
return this.name;
}
public void setName(String s) {
this.name = s;
this.noAccentName = RemoveDiacritics(name); //remove diacritics from name
}
@Column(name = "noaccent_name")
public String getNoAccentName() {
return this.noAccentName;
}
public void setNoAccentName(String s) {
this.noAccentName = s;
}
这是有效但它有一个开销:名称的setter将object设置为dirty,而hibernate想要一直更新它... :(
当'name'以干净的方式更改时,如何让hibernate更新'noAccentName'?
非常感谢。
答案 0 :(得分:3)
你找到了拦截器,但是从Hibernate 4开始,这样做的推荐方法是使用Callback methods。事实上,我根本找不到Hibernate 4中的拦截器,所以如果你这样做,你可能没有升级路径。
我相信你想要做的是:
@Column(name = "name")
public String getName() {
return this.name;
}
public void setName(String s) {
this.name = s;
}
@PrePersist
private void updateNoAccentName() {
this.noAccentName = RemoveDiacritics(this.name);
}
@Column(name = "noaccent_name")
public String getNoAccentName() {
return this.noAccentName;
}
private void setNoAccentName(String s) {
this.noAccentName = s;
}
然后,Hibernate将在保存对象之前负责更新noAccentName。请注意,我还将setNoAccentName方法设为私有,因为无法将noAccentName转换为name并获得正确的重音。
答案 1 :(得分:1)
我找到了解决方案。 :)它的名字是hibernate拦截器。
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/events.html
在一个简单的拦截器的帮助下,我可以根据另一个更新noAccent字段。
感谢您的时间和精力,
答案 2 :(得分:0)
在给定name的值的情况下,你总能得到noAccentName吗?如果是这样,您应该标记它以及getter和setter @Transient
,以便它们不再受到休眠的影响。只要设置了name,就设置noAccentName的值,除非name的值发生变化,否则hibernate不会更新该特定实例。
修改强> 或者,您可以尝试检查名称与正在分配的新名称相等,因此除非严格必要,否则不会分配任何字段(这会导致hibernate将其标记为脏)。如果仍然更新,则可能是因为hibernate配置为无论是否更新,或者因为其他字段也在更新。
答案 3 :(得分:0)
一种简单的方法是使用字段访问而不是属性访问,甚至可能只针对这两个属性(请参阅access type,不推荐)。
答案 4 :(得分:0)
我认为这是域名命名问题。此时调用setName时不仅要设置名称。像changeName这样改变两者值的另一种方法似乎更合适。虽然我同意Neil的观点,如果值始终是派生的,那么你在持久保存名称和更改名称方面没什么价值。如果您的应用程序是唯一使用该信息的应用程序,为什么不删除该列,只提供一个单独的访问器来删除diacricitals。