Hibernate:获取记录但是它正在数据库中更新?

时间:2010-12-24 08:06:16

标签: java hibernate

出于某种原因,Hibernate似乎保持我的会话打开并更新对象,而没有我明确地调用save / update / saveorupdate。我猜这个会议是开放的,它被标记为脏。

然而,这不是理想的行为,那么最简单的解决方法是什么呢?

问题似乎发生是因为我在数据库中存储了没有格式化的电话号码,但对象的获取者返回了格式化的电话号码。

我的流程: 转到jsp => controller => service =>道

DAO getter功能

if(userId != 0) {
   return (User)dbFactory.get(User.class, userId);
}
return null;

服务只是将它传递给控制器​​,控制器将te用户对象放入请求范围。我使用EL在JSP页面上显示它。

编辑: 我添加了以下内容: JSP:

<spring:bind path = "user.telephoneNumber">${user.telephoneNumber}</spring:bind>

控制器:

@InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(String.class, "telephoneNumber", new TelephoneNumberEditor(false));
    }

编辑: 公共类TelephoneNumberEditor扩展PropertyEditorSupport {     private boolean isRequired = false;

public TelephoneNumberEditor(boolean isRequired) {
    this.isRequired = isRequired;
}

public void setAsText(String text) throws IllegalArgumentException {
   String s = null;
    if (!this.isRequired && StringUtils.isBlank(text)) {
        setValue("");
    }
    else
    {
        s = text.replace("(0)","");
        s = s.replaceAll("[^0-9]", "");
        setValue(s);
    }
}

public String getAsText() {
    String telephoneNumber = (String) getValue();
    if(StringUtils.isBlank(telephoneNumber)){
        return "";
    } else {
        try {
            MaskFormatter formatter = new MaskFormatter("+AA AA AA AA AA");
            formatter.setValueContainsLiteralCharacters(false);
            return formatter.valueToString(telephoneNumber);
        } catch (ParseException e) {
            return "";
        }
    }
}

}

在控制器中,我将User对象作为用户放在请求范围内。

2 个答案:

答案 0 :(得分:1)

您可以为格式化的值创建另一个属性(getter和setter),并将其标记为瞬态(使用@Transient或在.hbm.xml中省略):

@Transient
public String getFormattedPhoneNumber() { ... }
public void setFormattedPhoneNumber(String number) { ... }

或者,您可以将Hibernate访问类型配置为使用字段而不是属性 - 在这种情况下,您的getter可以返回任意表示。

编辑:如果使用Spring MVC数据绑定,则可以在PropertyEditor中实现格式化逻辑。由于格式化电话号码是一种表示问题,因此将其移至表示层似乎是合理的:

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(String.class, "phoneNumber", 
        new PropertyEditorSupport() { ... });
}

在这种方法中,自定义编辑器在处理周期的典型Spring中自动工作(表单使用Spring form tags呈现,数据在POST时绑定到@ModelAttribute。如果您需要手动显示格式化值(在表单标记之外),可以使用<spring:bind>

<spring:bind path = "user.phoneNumber">${status.displayValue}</spring:bind>

(如果在user.内,则为<form:form>,我猜)

答案 1 :(得分:0)

如果要对持久对象进行非持久性更改,可以使用Session.evict(Object object)明确地将其置于上下文之外。在完成之后,Hibernate将不会保留您对其所做的任何更改。

关于它发生原因的描述并没有完全相加。您是否使用基于属性的访问来实现持久性,而不使用直接的getter-setter?标记价值的吸气剂可能会引起架构上的反对意见,但其本身不应该导致持久性问题。