【发布时间】:2014-10-15 09:17:39
【问题描述】:
我制作了一个自定义的@UniqueNombre 验证器来检查数据库中是否已经存在用户名,并且当它不重复并尝试持久化数据时,它会引发 Hibernate 异常:
ERROR org.hibernate.AssertionFailure - HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: null id in es.cesga.cloudpyme2.openinnovation.Usuario entry (don't flush the Session after an exception occurs)
验证器的代码是:
public class UniqueNombreValidator implements ConstraintValidator<UniqueNombre, String> {
@Override
public void initialize(UniqueNombre paramA) {
}
@Override
public boolean isValid(String nombre, ConstraintValidatorContext ctx) {
return (Usuario.countFindUsuariosByNombreEquals(nombre) == 0);
}
}
还有控制器:
@RequestMapping(method = RequestMethod.POST, produces = "text/html")
public String create(@Valid Usuario usuario, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) {
if (bindingResult.hasErrors()) {
populateEditForm(uiModel, usuario);
return "usuario/create";
}
uiModel.asMap().clear();
setUpUsuario(usuario, httpServletRequest);
usuario.persist();
return "redirect:/usuario/" + encodeUrlPathSegment(usuario.getIdUsuario().toString(), httpServletRequest);
}
如果不检查重复的用户名,控制器就会像魅力一样工作。有什么想法吗?
更新:这是验证器内部使用的方法:
public static Long Usuario.countFindUsuariosByNombreEquals(String nombre) {
if (nombre == null || nombre.length() == 0) throw new IllegalArgumentException("The nombre argument is required");
EntityManager em = Usuario.entityManager();
TypedQuery q = em.createQuery("SELECT COUNT(o) FROM Usuario AS o WHERE o.nombre = :nombre", Long.class);
q.setParameter("nombre", nombre);
return ((Long) q.getSingleResult());
}
【问题讨论】:
-
您的交易是如何组织的?我想
usuario.persist()写入数据库,那么如果是事务性对象呢? -
在该检查用户名请求时可能未创建会话。如果您使用 spring-security 这需要将
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)添加到 httpSecurity 配置。 -
问题是,当用户名已经被使用时,它可以正常工作并在表单中显示错误消息,但是当用户名尚未被使用时,它会崩溃。 @px5x2,如果我使用的是 applicationContext-security.xml 文件,我应该在哪里添加 sessionCreationPolicy(...)?
-
@SergeBallesta,很抱歉,我不明白你的问题。
-
您在休眠时出错。众所周知,Hibernate + spring 在尝试访问事务之外的数据库时会导致问题。我想这可能是你的错误的原因,但我需要知道你如何管理你的休眠事务。我认为这是休眠会话的问题,而不是 http 会话...
标签: java spring hibernate spring-roo validation