MapStruct игнорирует поля - PullRequest
       11

MapStruct игнорирует поля

1 голос
/ 27 октября 2019

Я новичок в Java Spring Boot. Я решил использовать MapStruct, потому что он похож на AutoMapper ASP.NET Core.

Проблема:

enter image description here

Изображение довольно понятно,Это не сопоставляет firstName и lastName. Я думал, что это может быть подчеркивание, например, first_name, но затем я добавил пароль в модель DTO, и он тоже не устанавливается.

enter image description here

Кстати, я проверил это, удалив модель DTO со следующим кодом, и это сработало, что означает, что причина в том, что UserMapper.

@GetMapping
public ResponseEntity<List<User>> getAll() {
    return ResponseEntity.ok(userService.getAll());
}

Журнал из ReportingPolicy.WARN

2019-10-27 15:58:44.024 DEBUG 24284 --- [nio-5000-exec-1] org.hibernate.SQL                        : select user0_.id as id1_2_, user0_.email as email2_2_, user0_.first_name as first_na3_2_, user0_.last_name as last_nam4_2_, user0_.password as password5_2_ from users user0_
2019-10-27 15:58:44.033 DEBUG 24284 --- [nio-5000-exec-1] org.hibernate.SQL                        : select roles0_.user_id as user_id1_1_0_, roles0_.role_id as role_id2_1_0_, role1_.id as id1_0_1_, role1_.description as descr

UserMapper.java

package com.holding.server.mappers;

import java.util.List;

import com.holding.server.dto.UserDTO;
import com.holding.server.entities.User;

import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.WARN)
public interface UserMapper {

    UserDTO toUserDTO(User user);

    List<UserDTO> toUserDTOs(List<User> users);

    User toUser(UserDTO userDTO);
}

User.java

package com.holding.server.entities;

import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder

@Entity(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true)
    @NotNull
    @Size(max = 40)
    @Email
    private String email;

    @NotNull
    private String password;

    @NotNull
    @Size(max = 40)
    private String firstName;

    @NotNull
    @Size(max = 40)
    private String lastName;

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"))
    private Set<Role> roles;
}

UserDTO.java

package com.holding.server.dto;

import lombok.Data;

@Data
public class UserDTO {

    private String email;
    private String firstName;
    private String lastName;
}

UserServiceImpl.java

package com.holding.server.services;

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

import com.holding.server.entities.User;
import com.holding.server.repositories.UserRepository;
import com.holding.server.services.UserService;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import lombok.AllArgsConstructor;

@AllArgsConstructor

@Service
public class UserServiceImpl implements UserService {

    private UserRepository userRepository;
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    public List<User> getAll() {
        return userRepository.findAll();
    }

    @Override
    public Optional<User> get(Long id) {
        return userRepository.findById(id);
    }

    @Override
    public Optional<User> create(User user) {
        if (userRepository.findByEmail(user.getEmail()).isPresent()) {
            return Optional.empty();
        }

        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        return Optional.ofNullable(userRepository.save(user));
    }

    @Override
    public Optional<User> update(User user) {
        Optional<User> userToUpdate = get(user.getId());

        if (userToUpdate.isPresent()) {
            userToUpdate.get().setFirstName(user.getFirstName());
            userToUpdate.get().setLastName(user.getLastName());
            userToUpdate.get().setRoles(user.getRoles());

            if (user.getPassword() != null) {
                userToUpdate.get().setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
            }

            return Optional.ofNullable(userRepository.save(userToUpdate.get()));
        }

        return Optional.empty();
    }

    @Override
    public void delete(Long id) {
        Optional<User> user = get(id);
        if (user.isPresent()) {
            userRepository.delete(user.get());
        }
    }
}

UserController.java

package com.holding.server.controllers;

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

import com.holding.server.dto.UserDTO;
import com.holding.server.entities.User;
import com.holding.server.mappers.UserMapper;
import com.holding.server.services.UserService;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import lombok.AllArgsConstructor;

@AllArgsConstructor

@RestController
@RequestMapping("/api/users")
public class UserController {

    private UserService userService;
    private UserMapper userMapper;

    @GetMapping
    public ResponseEntity<List<UserDTO>> getAll() {
        return ResponseEntity.ok(userMapper.toUserDTOs(userService.getAll()));
    }

    @GetMapping("/{id}")
    public ResponseEntity<UserDTO> get(@PathVariable("id") Long id) {
        Optional<User> user = userService.get(id);
        if (user.isPresent()) {
            return ResponseEntity.ok(userMapper.toUserDTO(user.get()));
        }

        return ResponseEntity.notFound().build();
    }

    @PostMapping
    public ResponseEntity<UserDTO> create(@RequestBody UserDTO userDTO) {
        User user = userMapper.toUser(userDTO);
        user.setId(null);

        Optional<User> savedUser = userService.create(user);
        if (savedUser.isPresent()) {
            return ResponseEntity.ok(userMapper.toUserDTO(savedUser.get()));
        }

        return ResponseEntity.status(HttpStatus.CONFLICT).build();
    }

    @PutMapping("/{id}")
    public ResponseEntity<UserDTO> update(@PathVariable(required = true) Long id, @RequestBody UserDTO userDTO) {
        User user = userMapper.toUser(userDTO);
        user.setId(id);

        Optional<User> updatedUser = userService.update(user);
        if (updatedUser.isPresent()) {
            return ResponseEntity.ok(userMapper.toUserDTO(updatedUser.get()));
        }

        return ResponseEntity.badRequest().build();
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> delete(@PathVariable(required = true) Long id) {
        if (userService.get(id).isPresent()) {
            userService.delete(id);
            return ResponseEntity.ok().build();
        }

        return ResponseEntity.notFound().build();
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<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.2.0.RELEASE</version>
    <relativePath />
  </parent>
  <groupId>com.holding</groupId>
  <artifactId>server</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>demo</name>
  <description>Demo project for Spring Boot</description>
  <properties>
    <java.version>1.8</java.version>
    <org.mapstruct.version>1.3.1.Final</org.mapstruct.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-security</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </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.springframework.security</groupId>
      <artifactId>spring-security-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <scope>runtime</scope>
    </dependency>

    <dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct</artifactId>
      <version>${org.mapstruct.version}</version>
    </dependency>
    <dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct-processor</artifactId>
      <version>${org.mapstruct.version}</version>
    </dependency>

    <dependency>
      <groupId>io.jsonwebtoken</groupId>
      <artifactId>jjwt</artifactId>
      <version>0.9.1</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.datatype</groupId>
      <artifactId>jackson-datatype-jsr310</artifactId>
      <version>2.10.0</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

Если вам нужно что-то еще,спроси меня.

1 Ответ

3 голосов
/ 27 октября 2019

MapStruct создает сгенерированный класс во время компиляции. Возможно, вы захотите очистить и перестроить, а затем проверить, содержит ли сгенерированный Mapper требуемые сопоставления.

...