@RequestMapping(value = "/updatetag", method = RequestMethod.POST)
public String updateTag(
@ModelAttribute("tag") Tag tag,
@Valid Tag validTag,
BindingResult result,
ModelMap map) {
if(result.hasErrors()) { // you don't care : validation of other
return "editTag"; // constraints like @NotEmpty
}
try {
tagService.updateTag(tag); // try to update
return "redirect:/tags"; // <- if it works
}
catch (DataIntegrityViolationException ex) { // if it doesn't work
result.rejectValue("label", "Unique.tag.label"); // pass an error message to the view
return "editTag"; // same treatment as other validation errors
}
}
6条答案
按热度按时间tez616oj1#
可能的解决方案之一是创建自定义
@UniqueKey
约束(以及相应的验证器);为了查找数据库中已有的记录,向UniqueKeyValidator
提供EntityManager
(或HibernateSession
)的示例。实体管理器感知验证程序
约束验证程序因子实现
唯一密钥
唯一密钥验证程序
用法
测试
1dkrff032#
我认为使用Hibernate验证器(JSR 303)来实现这个目的是不明智的,或者更好的是它不是Hibernate验证器的目标。
JSR 303是关于bean验证的。这意味着检查一个字段是否设置正确。但是您需要的是比单个bean更广泛的范围。它在某种程度上是全局范围(关于此类型的所有Bean)。--我认为您应该让数据库处理此问题。在数据库中为列设置唯一约束(例如,使用
@Column(unique=true)
注解字段),数据库将确保字段是唯一的。无论如何,如果你真的想使用JSR 303,那么你需要创建你自己的注解和验证器。验证器必须访问数据库并检查是否有其他实体具有指定的值。-但我相信在正确的会话中从验证器访问数据库会有一些问题。
nxagd54h3#
一种可能性是将字段注解为@NaturalId
wi3ka0sx4#
您可以使用
@Column
属性,该属性可以设置为unique
。egdjgwm85#
我发现了一个棘手的解决办法。
首先,我对MySql数据库实现了唯一约束:
您可以看到,我管理的XML标签由一个唯一的标签和一个名为“XPath”的文本字段定义。
无论如何,第二步是简单地捕捉当用户试图做一个坏的更新时产生的错误。一个坏的更新是当试图用一个现有的标签替换当前的标签时。如果你保持标签不变,没有问题。所以,在我的控制器中:
这可能与@Unique模式冲突,但您也可以使用此脏方法来验证添加。
注意:还有一个问题:如果在异常之前捕获到其他验证错误,则将不显示关于唯一性的消息。
oiopk7p56#
这段代码是基于之前使用
EntityManager
实现的代码。如果有人需要使用HibernateSession
。使用HibernateSession
自定义注解。@
唯一密钥. java