Receiving an “Unsatisfied dependency expressed through field ‘userService’; nested exception”

Not sure what is happening here. The error is

Exception encountered during context initialization – cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘authenticationController’: Unsatisfied dependency expressed through field ‘userService’; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userService’ – Unsatisfied dependency expressed through constructor parameter 1″

Am I missing something here?

My controller –

import com.***.model.User;
import com.***.service.AuthTokenService;
import com.***.service.Authentication;
import com.***.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;


@Controller
@RestController
@RequestMapping("/api/v1")
public class AuthenticationController {

@Autowired
UserService userService;
AuthTokenService authTokenService;

@GetMapping(path = "/users")
public ResponseEntity<?> listUser() {
    List<User> resource = userService.getUser();
    return ResponseEntity.ok(resource);
}

@PostMapping(path = "/register")
public ResponseEntity<?> register(@RequestBody User newUser) {
    User user = userService.findUserByEmail(newUser.getEmail());
    User unconfirmedUser = userService.registerUser(newUser);
    return ResponseEntity.ok(unconfirmedUser);
}

My UserService –

import com.***.model.User;
import com.***.repository.UserRepository;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.List;

    @Service
    @Component
    @AllArgsConstructor
    public class UserService {

    @Autowired
    UserRepository userRepository;
    AuthTokenService authTokenService;
    EmailSenderService emailSenderService;

    void sendAuthenticationEmail(String userMail, String token) {
        final SimpleMailMessage mailMessage = new SimpleMailMessage();
        mailMessage.setTo(userMail);
        mailMessage.setSubject("Mail Confirmation Link!");
        mailMessage.setFrom("<Mail Service>");
        mailMessage.setText( "Thank you for joining ***! Please click below to activate your account." + "http://8080/api/v1/confirm?token=" + token);
        emailSenderService.sendEmail(mailMessage);
    }

    public User registerUser(User user) {
        final Authentication authenticationToken = new Authentication(user);
        authTokenService.saveAuthenticationToken(authenticationToken);
        sendAuthenticationEmail(user.getEmail(), authenticationToken.getUserToken());
        return userRepository.save(user);
    }

    public void confirmUser(Authentication authenticationToken) {
        final User user = authenticationToken.getUser();
        user.setEnabled(true);
        userRepository.save(user);
        authTokenService.deleteAuthenticationToken((long) authenticationToken.getId());
    }
}

Authentication –

import com.***.model.User;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;
import java.time.LocalDate;
import java.util.UUID;


@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Authentication {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String userToken;
    private LocalDate dateTimeCreated;

    @OneToOne(targetEntity = User.class, fetch = FetchType.EAGER)
    @JoinColumn(nullable = false, name = "id")
    private User user;

    Authentication(User user) {
        this.user = user;
        this.dateTimeCreated = LocalDate.now();
        this.userToken = UUID.randomUUID().toString();
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserToken() {
        return userToken;
    }

    public void setUserToken(String userToken) {
        this.userToken = userToken;
    }

    public LocalDate getDateTimeCreated() {
        return dateTimeCreated;
    }

    public void setDateTimeCreated(LocalDate dateTimeCreated) {
        this.dateTimeCreated = dateTimeCreated;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

Authentication token repo –

package com.***.repository;

import com.***.service.Authentication;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface AuthenticationTokenRepository extends CrudRepository<Authentication, Long> {

    Optional<Authentication> findAuthenticationToken(String token);

}

Picture of file structure HERE

Log of error

Answer

Based on your error it looks like you don’t know how to create JpqRepository method signature based queries. You can read about it here : https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods

I’m guessing that your method in AuthenticationTokenRepository called findAuthenticationToken(String someField) should be named findBySomeField(String someField). Also make sure you have getter for someField

Would be easier if you could provide your AuthenticationTokenRepository and Authenctication classes

Edit:

Change your method in AuthenticationTokenRepository to findByUserToken(String userToken)

Leave a Reply

Your email address will not be published. Required fields are marked *