I'm following Devtiro's guide, but I encountered an error that I shouldn't have according to his guide.
I'm trying to connect Spring Boot to a database (H2) for the first time.
Here's the error:
org.junit.jupiter.api.extension.ParameterResolutionException: Failed to resolve parameter [com.example.dao.impl.UserDaoImpl userTest] in constructor [public com.example.todolist.dao.impll.UserDaoImplIntegTest(com.example.dao.impl.UserDaoImpl)]: No qualifying bean of type 'com.example.dao.impl.UserDaoImpl' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at java.base/java.util.Optional.orElseGet(Optional.java:364)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.dao.impl.UserDaoImpl' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1880)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1406)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveDependency(AbstractAutowireCapableBeanFactory.java:471)
at org.springframework.beans.factory.annotation.ParameterResolutionDelegate.resolveDependency(ParameterResolutionDelegate.java:136)
at org.springframework.test.context.junit.jupiter.SpringExtension.resolveParameter(SpringExtension.java:342)
... 3 more
Here's the code:
UserDaoImplIntegTest.java
package com.example.todolist.dao.impll;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import com.example.dao.impl.UserDaoImpl;
import com.example.todolist.TestDataUtil;
import com.example.todolist.User;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest
@ExtendWith(SpringExtension.class)
public class UserDaoImplIntegTest {
private UserDaoImpl userTest;
@Autowired
public UserDaoImplIntegTest(UserDaoImpl userTest) {
this.userTest = userTest;
}
@Test
public void testThatUserCanBeCreatedAndRecalled() {
User user = TestDataUtil.createTestUser();
userTest.create(user);
Optional<User> result = userTest.find(user.getId());
assertThat(result).isPresent();
assertThat(result.get().getId()).isEqualTo(user.getId());
}
}
UserDaoImpl.java
package com.example.dao.impl;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Optional;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import org.springframework.lang.Nullable;
import com.example.dao.UserDao;
import com.example.todolist.User;
@Component
public class UserDaoImpl implements UserDao {
private final JdbcTemplate jdbcTemplate;
public UserDaoImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public void create(User user) {
jdbcTemplate.update("INSERT INTO users (id, email, password) VALUES (?, ?, ?)", user.getId(), user.getEmail(), user.getPassword());
}
@Override
public Optional<User> find(Long id) {
List<User> result = jdbcTemplate.query("SELECT id, email, password FROM users WHERE id = ? LIMIT 1",
new UserRowMapper(),
id
);
return result.stream().findFirst();
}
public static class UserRowMapper implements RowMapper<User> {
@Override
@Nullable
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
return User.builder()
.id(rs.getLong("id"))
.email(rs.getString("email"))
.password(rs.getString("password"))
.build();
}
}
}
UserDao.java
package com.example.dao;
import java.util.Optional;
import com.example.todolist.User;
public interface UserDao {
void create(User user);
Optional<User> find(Long id);
}
User.java
package com.example.todolist;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.annotation.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class User {
@Id
private Long id;
private String email;
private String password;
}
Application.properties
spring.application.name=todolist
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
Thanks in advance!
Tried searching for the root of ParameterResolutionException as well as NoSuchBeanDefinitionException and their solutions, yet it didn't help with anything
I also analysed Devtiros github repository (text), but that was no help either
Another thing I tried was moving the UserDaoImpl, UserDao and User classes to the same folder as the UserDaoImplIntegTest, yet it only gave me more errors at the end