出于某种原因,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对象作为用户放在请求范围内。
答案 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?标记价值的吸气剂可能会引起架构上的反对意见,但其本身不应该导致持久性问题。