spring 奇怪的异常:“名称不能为空或为空!”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22748721/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 06:38:18  来源:igfitidea点击:

Strange exception: "Name must not be null or empty!"

springhibernatemavenjpaspring-data

提问by Sam

I'm experiencing a strange error in a Spring project, which is the following:

我在 Spring 项目中遇到一个奇怪的错误,如下所示:

SEVERE: Servlet.service() for servlet [calzoneServlet] in context with path [/calzone] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Name must not be null or empty!; nested exception is java.lang.IllegalArgumentException: Name must not be null or empty!] with root cause java.lang.IllegalArgumentException: Name must not be null or empty!

严重:servlet [calzoneServlet] 的 Servlet.service() 在路径为 [/calzone] 的上下文中引发异常 [请求处理失败;嵌套异常是 org.springframework.dao.InvalidDataAccessApiUsageException: Name must not be null or empty!; 嵌套异常是 java.lang.IllegalArgumentException: Name must not be null or empty!] 根本原因 java.lang.IllegalArgumentException: Name must not be null or empty!

In this project, all models are mapped to the database using hibernate and jpa. The front-end uses Twitter Bootstrap (with spring form validation, etc)

在这个项目中,所有模型都使用 hibernate 和 jpa 映射到数据库。前端使用 Twitter Bootstrap(带有 spring 表单验证等)

The error occurs at different parts of the program, one of which is a controller to activate a user account (code below). To me this looks like some sort of validation error, but it isn't an error I have ever defined. Since I can't pinpoint the exact location of the error, I'll only provide the controller below. It is noteworthy that any debug messages (whether it be through the logger or just a plain old sysout) in the activateUsermethod do not get displayed.

该错误发生在程序的不同部分,其中之一是激活用户帐户的控制器(下面的代码)。对我来说,这看起来像是某种验证错误,但这不是我定义过的错误。由于我无法确定错误的确切位置,因此我将仅提供下面的控制器。值得注意的是,该方法中的任何调试消息(无论是通过记录器还是只是一个普通的旧系统输出)activateUser都不会显示。

All dependencies (pom.xml) can be found here: http://pastebin.com/fs7SG0W2Web.xml here: http://pastebin.com/vAJh29AwThe entire stacktrace can be found here: http://codepad.org/p0Yt5hi2(on codepad, because it has horizontal scrolling)

所有依赖项 (pom.xml) 都可以在这里找到:http: //pastebin.com/fs7SG0W2 Web.xml 在这里:http: //pastebin.com/vAJh29Aw 整个堆栈跟踪可以在这里找到:http: //codepad.org /p0Yt5hi2(在键盘上,因为它具有水平滚动功能)

Does anyone have any idea why this error could be happening, or have any clue as to how I can find out why it's happening?

有没有人知道为什么会发生这个错误,或者有什么线索可以知道我如何找出它发生的原因?

@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";
    }
}

回答by Emerson Farrugia

Your KeyServiceis calling some Spring Data JPA repository with a method findKeyByKeyString()method. That method is causing Spring Data JPA to explode because some query parameter is missing.

KeyService正在使用方法findKeyByKeyString()方法调用一些 Spring Data JPA 存储库。该方法导致 Spring Data JPA 爆炸,因为缺少某些查询参数。

Put a conditional breakpoint on org.springframework.data.jpa.repository.query.StringQuery.getBindingFor(StringQuery.java:104)that matches if !StringUtils.hasText(name)to see what's going on, or review the findKeyByKeyString()method.

org.springframework.data.jpa.repository.query.StringQuery.getBindingFor(StringQuery.java:104)如果!StringUtils.hasText(name)要查看发生了什么或查看findKeyByKeyString()方法,请在匹配项上放置条件断点。

回答by uthomas

EDIT: As @Gilbertoca pointed out I indeed had to use @Param. Source of my confusion was that I used @QueryParam annotation by accident.

编辑:正如@Gilbertoca 指出的那样,我确实必须使用@Param。我困惑的根源是我不小心使用了 @QueryParam 注释。

So if you use @Param it'll work.

所以如果你使用@Param 它会起作用。

Original response:

原回复:

I got exactly the same and took some time while I figured out what was the problem: I used JpaRepository interface with a method annotated like

我完全一样,花了一些时间才弄清楚问题出在哪里:我使用了 JpaRepository 接口和一个注释如下的方法

@Query(value = "SELECT * FROM table WHERE property=:something", nativeQuery = true).

As it turned out in this context named parameters are not supported. It started to work for me after I changed to:

事实证明,在此上下文中不支持命名参数。在我改为:

@Query(value = "SELECT * FROM table WHERE property=(?1)", nativeQuery = true).

(brackets are important, otherwise it didn't work).

(括号很重要,否则它不起作用)。

回答by Arun Gopalpuri

I had the same exception and I was missing @Param("appname") in method args:

我有同样的例外,我在方法 args 中缺少 @Param("appname") :

@Query("SELECT p.preferenceId.userId FROM Preference p WHERE p.preferenceId.appName = :appname") List getAppUsers(@Param("appname")String appname);

@Query("SELECT p.preferenceId.userId FROM Preference p WHERE p.preferenceId.appName = :appname") List getAppUsers( @Param("appname")String appname);