Im keep getting this error: Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled. 2023-08-06T16:52:30.116-04:00 ERROR 36962 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
APPLICATION FAILED TO START
Description:
Parameter 1 of constructor in com.saferent.saferent.controller.ContactMessageController required a bean of type 'com.saferent.saferent.mapper.ContactMessageMapper' that could not be found.
Action:
Consider defining a bean of type 'com.saferent.saferent.mapper.ContactMessageMapper' in your configuration.
Process finished with exit code 0
Applicaiton should run
====MY CODES====
package com.saferent.saferent.controller;
import com.saferent.saferent.domain.ContactMessage;
import com.saferent.saferent.dto.ContactMessageDTO;
import com.saferent.saferent.dto.request.ContactMessageRequest;
import com.saferent.saferent.dto.response.SfResponse;
import com.saferent.saferent.mapper.ContactMessageMapper;
import com.saferent.saferent.service.ContactMessageService;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/contactmessage")
public class ContactMessageController {
recommended. why? has security safety issues.
private final ContactMessageService contactMessageService; //best to do construction injection
private final ContactMessageMapper contactMessageMapper;
@Autowired
public ContactMessageController(ContactMessageService contactMessageService, ContactMessageMapper contactMessageMapper) {
this.contactMessageService = contactMessageService;
this.contactMessageMapper = contactMessageMapper;
}
@PostMapping("/visitors")
public ResponseEntity<SfResponse> createMessage(@Valid @RequestBody ContactMessageRequest contactMessageRequest){
ContactMessage contactMessage=
contactMessageMapper.contactMessageRequestToContactMessage(contactMessageRequest);
contactMessageService.saveMessage(contactMessage);
SfResponse response=new SfResponse("ContactMessage successfully created",true);//we can put new here cuz we are creating this once
return new ResponseEntity<>(response, HttpStatus.CREATED);
}
@GetMapping
public ResponseEntity<List<ContactMessageDTO>>getAllContactMessage(){
List<ContactMessage>contactMessageList= contactMessageService.getAll();//this will get POJO cuz it gets it directly from DB
List<ContactMessageDTO>contactMessageDTOList=contactMessageMapper.map(contactMessageList);
return ResponseEntity.ok(contactMessageDTOList);
}
@GetMapping("/pages")
public ResponseEntity<Page<ContactMessageDTO>>getAllContactMesssageWithPage(
@RequestParam("page") int page,
@RequestParam("size") int size,
@RequestParam("sort") String prop,//defines how its sorted
@RequestParam(value = "direction",
required = false,defaultValue = "DESC")Sort.Direction direction) {
Pageable pageable = PageRequest.of(page, size, Sort.by(direction, prop));
Page<ContactMessage> contactMessagePage = contactMessageService.getAll(pageable);
Page<ContactMessageDTO>pageDTO= getPageDTO(contactMessagePage);
return ResponseEntity.ok(pageDTO);
}
private Page<ContactMessageDTO>getPageDTO(Page<ContactMessage>contactMessagePage){
return contactMessagePage.map(
contactMessage -> contactMessageMapper.contactMessageToDTO(contactMessage));
}
}
package com.saferent.saferent.domain;
import jakarta.persistence.*;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.*;
import org.springframework.stereotype.Service;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name="tbl_cmessage")
public class ContactMessage {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Setter(AccessLevel.NONE)
private Long id;//we use Long so we can get null not a number if nothing is giver
@Size(min = 1,max = 50,message = "Your name '${validatedValue}' must be between {min} and {max} chars long")
@NotNull(message = "please provide your name")
@Column(length = 50,nullable = false)
private String name;
@Size(min = 5,max = 50,message = "Your subject '${validatedValue}' must be between {min} and {max} chars long")
@NotNull(message = "please provide your subject")
@Column(length = 50,nullable = false)
private String subject;
@Size(min = 20,max = 200,message = "Your body '${validatedValue}' must be between {min} and {max} chars long")
@NotNull(message = "please provide your body")
@Column(length = 200,nullable = false)
private String body;
@Email(message = "Provide valid email")
@Column(length = 50,nullable = false)
private String email;
}
package com.saferent.saferent.mapper;
import com.saferent.saferent.domain.ContactMessage;
import com.saferent.saferent.dto.ContactMessageDTO;
import com.saferent.saferent.dto.request.ContactMessageRequest;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.springframework.stereotype.Component;
import java.util.List;
@Mapper(componentModel = "spring")
@Component
public interface ContactMessageMapper {
ContactMessageDTO contactMessageToDTO(ContactMessage contactMessage);
contactMessageToDTO(ContactMessage contactMessage); we do not need to fill it in cuz it gets it from the dependencies we have.
@Mapping(target = "id",ignore = true)//Ignoring id in request class when mapping.
ContactMessage contactMessageRequestToContactMessage(ContactMessageRequest contactMessageRequest);
List<ContactMessageDTO>map(List<ContactMessage> contactMessageList);//getAllContactMessage()
}
package com.saferent.saferent;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class SaferentApplication {
public static void main(String[] args) {
SpringApplication.run(SaferentApplication.class, args);
}
}
===== 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.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.saferent</groupId>
<artifactId>saferent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>saferent</name>
<description>Car Rental Backend Project</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</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>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.mapstruct</groupId>-->
<!-- <artifactId>mapstruct</artifactId>-->
<!-- <version></version>-->
<!-- </dependency>-->
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.3.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok-mapstruct-binding -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>