Home > Mobile >  Error in creating bean userController caused by Could not create query for public abstract java.util
Error in creating bean userController caused by Could not create query for public abstract java.util

Time:04-26

Stack trace: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController': Unsatisfied dependency expressed through field 'userRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository' defined in br.com.allen.flashfood.domain.repository.UserRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.Optional br.com.allen.flashfood.domain.repository.CustomJpaRepository.findFirst()! Reason: Failed to create query for method public abstract java.util.Optional br.com.allen.flashfood.domain.repository.CustomJpaRepository.findFirst()! No property findFirst found for type User!; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.Optional br.com.allen.flashfood.domain.repository.CustomJpaRepository.findFirst()! No property findFirst found for type User!

Classes:

  • Controller:
package br.com.allen.flashfood.api.controller;

import br.com.allen.flashfood.api.assembler.UserModelAssembler;
import br.com.allen.flashfood.api.assembler.UserRequestDisassembler;
import br.com.allen.flashfood.api.model.request.PasswordRequest;
import br.com.allen.flashfood.api.model.request.UserPasswordRequest;
import br.com.allen.flashfood.api.model.request.UserRequest;
import br.com.allen.flashfood.api.model.response.UserResponse;
import br.com.allen.flashfood.domain.model.User;
import br.com.allen.flashfood.domain.repository.UserRepository;
import br.com.allen.flashfood.domain.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserService userService;

    @Autowired
    private UserModelAssembler userModelAssembler;

    @Autowired
    private UserRequestDisassembler userRequestDisassembler;

    @GetMapping
    public List<UserResponse> getAllUsers() {
        List<User> allUsers = userRepository.findAll();
        return userModelAssembler.toCollectionModel(allUsers);
    }

    @GetMapping("/{userId}")
    public UserResponse getUserById(@PathVariable Long userId) {
        User user = userService.findUserOrElseThrow(userId);
        return userModelAssembler.toModel(user);
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public UserResponse addUser(@RequestBody @Valid UserPasswordRequest userPasswordRequest) {
        User user = userRequestDisassembler.toDomainObject(userPasswordRequest);
        user = userService.saveUser(user);
        return userModelAssembler.toModel(user);
    }

    @PutMapping("/{userId}")
    public UserResponse updateUser(@PathVariable Long userId,
                                   @RequestBody @Valid UserRequest userRequest) {
        User actualUser = userService.findUserOrElseThrow(userId);
        userRequestDisassembler.copyToDomainObject(userRequest, actualUser);
        actualUser = userService.saveUser(actualUser);
        return userModelAssembler.toModel(actualUser);
    }

    @PutMapping("/{userId}/password")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void userPassword(@PathVariable Long userId,
                             @RequestBody @Valid PasswordRequest passwordRequest) {
        userService.changePassword(userId, passwordRequest.getActualPassword(), passwordRequest.getNewPassword());
    }
}

Repository:

package br.com.allen.flashfood.domain.repository;

import br.com.allen.flashfood.domain.model.User;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends CustomJpaRepository<User, Long> {
}

CustomJpaRepository

package br.com.allen.flashfood.domain.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;

import java.util.Optional;

@NoRepositoryBean
public interface CustomJpaRepository<T, ID> extends JpaRepository<T, ID> {
    Optional<T> findFirst();
}

User:

package br.com.allen.flashfood.domain.model;

import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.CreationTimestamp;

import javax.persistence.*;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;

@Entity
@Data
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @EqualsAndHashCode.Include
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String email;

    @Column(nullable = false)
    private String password;

    @CreationTimestamp
    @Column(nullable = false, columnDefinition = "datetime")
    private OffsetDateTime registrationDate;

    @ManyToMany
    @JoinTable(name = "user_group",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "group_id"))
    private List<Family> groups = new ArrayList<>();

    public boolean passwordConfirmed(String password) {
        return getPassword().equals(password);
    }

    public boolean passwordNotConfirmed(String password) {
        return !passwordConfirmed(password);
    }
}

Edit 1: I had forgotten to put the implementation in question because I thought it couldn't be that by editing the question now.

package br.com.allen.flashfood.infrastructure.repository;

import br.com.allen.flashfood.domain.repository.CustomJpaRepository;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;

import javax.persistence.EntityManager;
import java.util.Optional;

public class CustomJpaRepositoryImpl<T, ID> extends SimpleJpaRepository<T, ID> implements CustomJpaRepository<T, ID> {
    private EntityManager entityManager;

    public CustomJpaRepositoryImpl(JpaEntityInformation<T, ?> entityInformation,
                                   EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.entityManager = entityManager;
    }

    @Override
    public Optional<T> findFirst() {
        var jpql = "from "   getDomainClass().getName();
        T entity = entityManager.createQuery(jpql, getDomainClass())
                .setMaxResults(1)
                .getSingleResult();
        return Optional.ofNullable(entity);
    }
}

CodePudding user response:

The method findFirst() does not exist by itself. You need to add more expressions to this, such as findFirstByName(String name). In other words, you won't be able to create a superclass with a findFirst method that can be properly inherited. I don't really see a case here where I would create yet another interface to extend, you'll probably be better off just extending JpaRepository from your UserRepository.

  • Related