使用H2的Java Spring项目中的查询问题

时间:2019-06-11 18:42:42

标签: spring spring-boot spring-mvc spring-security spring-data-jpa

我有一个使用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上注释查询行时,程序将运行,但不会搜索登录名。

UserDAO

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();

}

UserModel#

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 个答案:

答案 0 :(得分:2)

在DAO中

upload.emit("finish"); // must emit after subscribing

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

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