Сопоставьте класс домена с классом DTO, используя Mapstruct и lombok в приложении SpringBoot с RestController

#dto #lombok #spring-restcontroller #mapstruct

#дто #ломбок #spring-restcontroller #mapstruct

Вопрос:

Ниже приведен мой основной класс приложения.

 @SpringBootApplication
@EnableAutoConfiguration
@ComponentScan("com.example.demo")
public class Demo1Application {

    public static void main(String[] args) {
        SpringApplication.run(Demo1Application.class, args);
    }

}
  

Класс контроллера.

 @RestController
public class JobAppController {
    
    @Autowired
    JobApplicationRepository jobApplicationRepository;
    
    //@Autowired
    //private JobApplicationMapper mapper;
    
    JobApplicationMapper mapper = Mappers.getMapper(JobApplicationMapper.class);
    
    @GetMapping("/hello")
    public String greeting()
    {
        return "hello Mr";
    }
    
    @PostMapping("/save")
    public JobApplicationDto save(@RequestBody JobApplicationDto jobApplicationDto)
    {
        JobApplication jobApplication = mapper.toEntity(jobApplicationDto);
        jobApplication = jobApplicationRepository.save(jobApplication);
        return mapper.ToDTO(jobApplication);
        
    }

}
  

Интерфейс Mapper.

 @Mapper
@Component
public interface JobApplicationMapper {

    //JobApplicationMapper mapper = Mappers.getMapper(JobApplicationMapper.class);
    //({ @Mapping(target="employeeId", source="entity.id"),@Mapping(target="employeeName", source="entity.name")})
    
    JobApplicationDto  ToDTO(JobApplication jobApplication);
    JobApplication toEntity(JobApplicationDto jobApplicationDto);
}
  

мой pom-файл.

 <?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>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.jobSearch</groupId>
    <artifactId>demo-1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo-1</name>
    <description>Demo project for Spring Boot/JobSearch</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
    <!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
        <dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-jdk8</artifactId>
    <version>1.3.0.Final</version>
       </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-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</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>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
     <groupId>org.apache.commons</groupId>
     <artifactId>commons-lang3</artifactId>
     <version>3.3.2</version>
     <type>jar</type>
</dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.5.1</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <annotationProcessorPaths>
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>1.3.0.Beta2</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>
        </plugins>
    </build>

</project>
  

класс домена.

     @Entity
    @Table(name = "Job_Application")
    //@Data
    //@AllArgsConstructor
    //@NoArgsConstructor
    public class JobApplication {
        
        
        
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Id()
        private Integer id;
    
        @Column(name = "requisition_id")
        private String requisition_id;
    
        @Column(name = "job_posting_source")
        private String job_posting_source;
    
        @Column(name = "applied_date")
        private Date applied_date;
    
        @Column(name = "company")
        private String company;
    
        @Column(name = "current_status")
        private String current_status;
    
        @Column(name = "position")
        private String position;
    
        @Column(name = "location")
        private String location;
//getters and setters follows...
  

класс dto.

     /*@Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder*/
    public class JobApplicationDto {
        
        private Integer id;
        private String requisition_id;
        private String job_posting_source;
        private Date applied_date;
        private String company;
        private String current_status;
        private String position;
        private String location;
//getters and setters follows
  

при попытке опубликовать данные / dto (как JSON) в моей таблице db через postman, данные вставляются как нулевые значения

 {
  "requisition_id" : "1234",
  "job_posting_source" : "indeed",
  "applied_date" : "2020-08-15",
  "company" : "softInc",
  "current_status" : "under review",
  "position" : "SE3",
  "location" : "Himalayas"
}
  

ответ после вставки выглядит следующим образом

 {
    "id": null,
    "requisition_id": null,
    "job_posting_source": null,
    "applied_date": null,
    "company": null,
    "current_status": null,
    "position": null,
    "location": null
}
  

Сообщения об ошибке нет. не уверен, чего мне не хватает.
После тщательной отладки я понял, что с реализацией mapper проблем нет. однако, поскольку я использую «lombok» для домена и классов dto, получатели и установщики не генерировались. Поэтому я вручную добавил их сейчас в код и теперь работает так, как ожидалось.

PS: Я бы оценил себя как новичка в этом деле, поэтому приветствуются любые обсуждения / предложения.

Я бы отредактировал вопрос сейчас, поскольку проблема связана с lombok относительно того, почему не генерируются геттеры / сеттеры.

Ответ №1:

Я думаю, что Lombok отсутствует в качестве процессора аннотаций..

Попробуйте:

 <annotationProcessorPaths>
    <path>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>${org.mapstruct.version}</version>
    </path>
    <path>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${org.projectlombok.version}</version>
    </path>
</annotationProcessorPaths>

  

Проверьте это для рабочего примера.

Пожалуйста, обратите внимание: есть несколько проблем с Lombok / MapStruct. Оба являются процессорами аннотаций. Lombok генерирует геттеры / сеттеры, MapStruct использует их. Время имеет важное значение. Следовательно, MapStruct ввел SPI для обозначения готовности генерации.

Комментарии:

1. Правильно … понял это после просмотра моего файла pom. Спасибо за ваш ответ. Я убедился, что он работает должным образом после добавления процессора аннотаций lombok.