hibernate:根据另一个更新列

时间:2012-04-19 12:41:56

标签: java hibernate

我有一个包含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'?

非常感谢。

5 个答案:

答案 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。