Issue
I'm trying to setup a simple endpoint for accessing a MySQL database, with one createAccount() method, but it seems as if Spring Boot is not able to wire/create beans through all of my classes.
Here's the code details:
MykitchenresourcesApplication
package com.it326.mykitchenresources;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@SpringBootApplication
@ComponentScan(basePackages = "com.it326.mykitchenresources.*")
@EntityScan("com.it326.mykitchenresources.*")
@EnableJpaRepositories("com.it326.mykitchenresources.*")
public class MykitchenresourcesApplication {
public static void main(String[] args) {
SpringApplication.run(MykitchenresourcesApplication.class, args);
}
}
AccountController
package com.it326.mykitchenresources.controllers;
// Imports
@RestController
@RequestMapping("/account")
public class AccountController {
private final AccountService accountService;
@Autowired
public AccountController(AccountService accountService) {
this.accountService = accountService;
}
@RequestMapping("/hello")
public String hello() {
return "Hello, world!";
}
@PostMapping("/create")
public ResponseEntity<String> createAccount(@RequestBody AccountDTO accountDTO) {
// Retrieve values from the DTO (Data Transfer Object)
String name = accountDTO.getName();
String username = accountDTO.getUsername();
String password = accountDTO.getPassword();
// Create the account
Account createdAccount = accountService.createAccount(name, username, password);
if (createdAccount != null) {
return ResponseEntity.status(HttpStatus.CREATED).body("Account created successfully");
} else {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to create account");
}
}
}
AccountService
package com.it326.mykitchenresources.services;
// Imports
@Service
public class AccountService {
@Autowired
private final AccountDb accountDb;
public AccountService(AccountDb accountDb) {
this.accountDb = accountDb;
}
public Account createAccount(String name, String username, String password) {
Account account = new Account();
account.setName(name);
account.setUserName(username);
account.setHashedPassword(hashPassword(password));
return accountDb.save(account);
}
private String hashPassword(String password) {
// Generate a salt and hash the password using BCrypt
String salt = BCrypt.gensalt();
return BCrypt.hashpw(password, salt);
}
}
AccountDb (my repository class)
package com.it326.mykitchenresources.dbs;
// Imports
@Repository
public interface AccountDb extends JpaRepository<Account, Integer> {
Account findByUsername(String username);
}
Account (my entity class)
package com.it326.mykitchenresources.entities;
// Imports
@Entity
@Table(name = "accounts")
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "account_id")
private int accountId;
@Column(name = "name", length = 45)
private String name;
@Column(name = "username", length = 45)
private String username;
@Column(name = "hashed_password", length = 45)
private String hashedPassword;
// Constructors, getters, setters, etc.
public Account(){}
public Account(int accountId, String name, String username, String hashedPassword){
this.accountId = accountId;
this.name = name;
this.username = username;
this.hashedPassword = hashedPassword;
}
public int getAccountId() {
return accountId;
}
public void setAccountId(int accountId) {
this.accountId = accountId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUserName() {
return username;
}
public void setUserName(String username) {
this.username = username;
}
public String getHashedPassword() {
return hashedPassword;
}
public void setHashedPassword(String hashedPassword) {
this.hashedPassword = hashedPassword;
}
}
application.properties
spring.datasource.url= // My URL is here.
spring.datasource.username= // Same with my username
spring.datasource.password= // And my password
server.port=8081
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
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 https://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>3.1.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.it326</groupId>
<artifactId>mykitchenresources</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mykitchenresources</name>
<description>Backend for myKitchen</description>
<properties>
<java.version>17</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-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Password Hashing Dependency -->
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>0.4</version> <!-- or the latest version available -->
</dependency>
<!-- Database Connection Dependencies -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.5.7.Final</version> <!-- Use the appropriate version -->
</dependency>
<!-- Testing Dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder-jammy-base:latest</builder>
</image>
</configuration>
</plugin>
</plugins>
</build>
</project>
I've tried throwing all of my classes into the same package as the main application, but it seems that this does not remedy my issue.
I've also just tried mvn clean install without any of the classes as a sanity check that my main application was working okay, and it worked fine.
The logs and error I'm getting:
o.s.w.c.s.GenericWebApplicationContext : Exception encountered during context initialization -
cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'accountController' defined in file [C:\Users\...\target\classes\com\it326\mykitchenresources\controllers\AccountController.class]:
Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'accountService' defined in file [C:\Users\...\target\classes\com\it326\mykitchenresources\services\AccountService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'accountDb' defined in com.it326.mykitchenresources.dbs.AccountDb defined in @EnableJpaRepositories declared on MykitchenresourcesApplication: Not a managed type: class com.it326.mykitchenresources.entities.Account
This is my first time setting up a Spring Boot project on my own, so I may be missing something completely obvious and staring me in the face; any help and pointers would be well appreciated! Thank you!
Solution
As already stated in the comment you should remove the explicit dependency to hibernate-core. This one:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.5.7.Final</version> <!-- Use the appropriate version -->
</dependency>
After doing it you should check all imports used in your classes. Especially the entity classes. There should be no imports from javax.persistence package. Only from jakarta.persistence. Otherwise you will have a mismatch of objects and errors like this: not a managed type.
Answered By - Mar-Z
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.