我在Spring项目中遇到一个奇怪的错误,如下所示:
SEVERE:servlet [calzoneServlet]的Servlet.service()在路径[/ calzone]的上下文中引发异常[请求处理失败;嵌套异常是org.springframework.dao.InvalidDataAccessApiUsageException:Name不能为null或为空!嵌套异常是java.lang.IllegalArgumentException:名称不能为null或为空!! java.lang.IllegalArgumentException:Name不能为null或为空!
在这个项目中,所有模型都使用hibernate和jpa映射到数据库。前端使用Twitter Bootstrap(带弹簧形式验证等)
错误发生在程序的不同部分,其中一个是激活用户帐户的控制器(下面的代码)。对我来说,这看起来像某种验证错误,但它不是我曾经定义的错误。由于我无法确定错误的确切位置,因此我将仅提供下面的控制器。值得注意的是,activateUser
方法中的任何调试消息(无论是通过记录器还是仅仅是普通的旧系统)都不会显示。
可以在此处找到所有依赖项(pom.xml):http://pastebin.com/fs7SG0W2 这里的Web.xml:http://pastebin.com/vAJh29Aw 整个堆栈跟踪可以在这里找到:http://codepad.org/p0Yt5hi2(在键盘上,因为它有水平滚动)
有没有人知道为什么会发生这种错误,或者有任何线索可以找出为什么会发生这种错误?
@Controller
public class ActivateAccountController {
final Logger logger = LoggerFactory.getLogger(getClass());
@RequestMapping(value = "/activate/{keyString}", method = RequestMethod.GET)
public String activateUser(@PathVariable String keyString) {
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
KeyService keyService = (KeyService) context.getBean("keyService");
UserService userService = (UserService) context.getBean("userService");
User user;
try {
logger.error("DID I GET HERE?");
user = keyService.findUserByKey(keyString);
} catch (KeyNotFoundException ex) {
return "ActivatedNotAccount";
} finally {
// Close the application context in every case
context.close();
}
// Activate the in-memory user
userService.activateUser(user);
// Delete the key from the database
keyService.deleteKey(keyString);
// Finally, update the user in the database
userService.updateUser(user);
logger.info("Acticated user with ID \"{}\", First name: \"{}\", Last name: \"{}\" and username: \"{}\"",
user.getId(), user.getPerson().getFirstName(), user.getPerson().getLastName(), user.getUsername());
return "ActivatedAccount";
}
}
答案 0 :(得分:10)
您的KeyService
正在使用方法findKeyByKeyString()
方法调用某些Spring Data JPA存储库。该方法导致Spring Data JPA爆炸,因为缺少某些查询参数。
将org.springframework.data.jpa.repository.query.StringQuery.getBindingFor(StringQuery.java:104)
上的条件断点与!StringUtils.hasText(name)
匹配,以查看正在进行的操作,或查看findKeyByKeyString()
方法。
答案 1 :(得分:9)
修改强>: 正如@Gilbertoca指出我确实不得不使用@Param。我混淆的原因是我偶然使用了@QueryParam注释。
因此,如果您使用@Param,它将会工作。
原始回复:
我得到了完全一样的东西,花了一些时间我才发现问题是什么: 我使用JpaRepository接口和注释类似
的方法@Query(value = "SELECT * FROM table WHERE property=:something", nativeQuery = true).
事实证明,在这种情况下,不支持命名参数。 在我改为:
后,它开始为我工作@Query(value = "SELECT * FROM table WHERE property=(?1)", nativeQuery = true).
(括号很重要,否则它不起作用)。
答案 2 :(得分:5)
我有同样的例外,我在方法args中缺少@Param(" appname"):
@Query(" SELECT p.preferenceId.userId FROM Preference p WHERE p.preferenceId.appName =:appname") 列出getAppUsers( @Param(" appname")字符串appname);