使用 H2 的 Java Spring 项目中的查询问题[关闭]

Posted

技术标签:

【中文标题】使用 H2 的 Java Spring 项目中的查询问题[关闭]【英文标题】:Problem with a query in a Java Spring project using H2 [closed] 【发布时间】:2019-10-26 05:53:39 【问题描述】:

我有一个使用 H2 作为数据库的项目,我试图在我的 UserDAO 上查询所有用户,但是当我尝试运行终端时出现很多错误并且无法启动服务器,但是当我注释查询的行时,程序运行正常。

错误

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'loginController': Unsatisfied dependency expressed through field 'usuarioservice'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'usuarioService' defined in file [/home/gustavolbs/PSOFT/back-end/lab3/target/classes/com/lab2/crud/service/UsuarioService.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDAO': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Using named parameters for method public abstract com.lab2.crud.model.User com.lab2.crud.dao.UserDAO.findByLogin(java.lang.String) but parameter 'Optional[searchLogin]' not found in annotated query 'Select u from User u where u.login=:plogin'!

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.lab2</groupId>
<artifactId>crud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>crud</name>
<description>Demo project for Spring Boot</description>

<properties>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.4</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.0</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

登录控制器

package com.lab2.crud.controller;

import java.util.Date;

import javax.servlet.ServletException;

import com.lab2.crud.model.User;
import com.lab2.crud.service.UsuarioService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

@RestController
@RequestMapping("/v1/auth")
public class LoginController 

    private final String TOKEN_KEY = "banana";

    @Autowired
    private UsuarioService usuarioService;

    @PostMapping("/login")
    public LoginResponse authenticate(@RequestBody User usuario) throws ServletException 

    // Recupera o usuario
    User authUsuario = usuarioService.findByLogin(usuario.getLogin());

    // verificacoes
    if(authUsuario == null) 
        throw new ServletException("Usuario nao encontrado!");
    

    if(!authUsuario.getPassword().equals(usuario.getPassword())) 
        throw new ServletException("Senha invalida!");
    

    String token = Jwts.builder().
            setSubject(authUsuario.getLogin()).
            signWith(SignatureAlgorithm.HS512, TOKEN_KEY).
            setExpiration(new Date(System.currentTimeMillis() + 1 * 60 * 1000))
            .compact();

        return new LoginResponse(token);


    

    private class LoginResponse 
        public String token;

        public LoginResponse(String token) 
            this.token = token;
        
    


UsuarioController

package com.lab2.crud.controller;

import com.lab2.crud.model.User;
import com.lab2.crud.service.UsuarioService;
import com.lab2.exception.Usuario.UsuarioJaExisteException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/v1/usuarios")
public class UsuarioController 

    @Autowired  
    private UsuarioService usuarioService;

    UsuarioController(UsuarioService usuarioService) 
        this.usuarioService = usuarioService;
    

    @PostMapping(value="/")
    public ResponseEntity<User> create(@RequestBody User usuario) 

        if (usuarioService.findByLogin(usuario.getLogin()) != null) 
            throw new UsuarioJaExisteException("Usuário já existe");
        

        User newUser = usuarioService.create(usuario);

        if (newUser == null) 
            throw new InternalError("Something went wrong");
        

        return new ResponseEntity<User>(newUser, HttpStatus.CREATED);
    


当我在 UserDAO 上注释查询行时,程序会运行,但它不会搜索登录名。

用户DAO

package com.lab2.crud.dao;

import java.io.Serializable;
import java.util.List;

import com.lab2.crud.model.User;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;


@Repository
public interface UserDAO<T, ID extends Serializable> extends JpaRepository<User, String> 

    User save(User usuario);
    User findById(long id);

    @Query("Select u from User u where u.login=:plogin")
    User findByLogin(@Param("searchLogin") String login);

    List<User> findAll();


用户模型#

package com.lab2.crud.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import lombok.Data;

@Data
@Entity
public class User 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private String name;
    private String login;
    private String password;

    public User() 

    

    public long getId() 
        return id;
    

    public String getName() 
        return name;
    

    public String getLogin() 
        return login;
    

    public String getPassword() 
        return password;
    

    public User(String name, String login, String password) 
        this.name = name;
        this.login = login;
        this.password = password;
    


application.properties

server.port = 8080

# H2
spring.h2.console.enabled=true
spring.h2.console.path=/h2
#indicará o path para você acessar a interface do h2, em geral, vá ao browser e coloque localhost:8080/h2 com 8080 ou sua porta

# Datasource
spring.datasource.url=jdbc:h2:file:~/PSOFT/back-end/lab3/test
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.hibernate.ddl-auto=update

server.servlet.context-path=/api
#diz ao spring que coloque /api antes de qualquer url, ou seja, se voce quiser utilizar as rotas /products, precisará adicionar /api =>  /api/v1/products e assim por diante

我尝试以其他方式重写查询,尝试重新导入包,在另一台机器上运行,但没有任何效果,我不知道解决什么以及为什么解决。谁能帮我解决这个问题?

【问题讨论】:

【参考方案1】:

在 DAO 中

@Query("Select u from User u where u.login=:plogin")
User findByLogin(@Param("searchLogin") String login);

您已使用 @Param 注释将 searchLogin 声明为参数,但在查询中您使用了 plogin 作为参数。将查询中的 plgin 替换为 searchLogin 如下所示,

@Query("Select u from User u where u.login=:searchLogin")
User findByLogin(@Param("searchLogin") String login);

【讨论】:

谢谢,用你的方法解决了! :D

以上是关于使用 H2 的 Java Spring 项目中的查询问题[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 应用程序中的 H2 Schema 为空

如何将 H2 嵌入式数据库读/写到 JAR 中的文件?

嵌入式。 H2 DB自动增量(Java测试用例)

在 Spring 项目中使用生成的 SQL 查询创建 H2 数据库时出现异常

无法加载驱动程序类:在 Spring Boot 应用程序中的 org.h2.Driver

如何使用 Netbeans Spring-Boot 项目访问 h2-console