Mapstruct找不到我的映射器的实现.使用最新版本的mapstruct 1.5.5最终版,我的IDE是ECLIPSE. 我得到了这个错误:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field productMapper in com.example.springshop.service.ImageService required a bean of type 'com.example.springshop.mapper.ProductMapper' that could not be found.
Action:
Consider defining a bean of type 'com.example.springshop.mapper.ProductMapper' in your configuration.
产品实体:
package com.example.springshop.entity;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.PrePersist;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Table(name = "products")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Product {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "title", nullable = false)
private String title;
@Column(name = "description", nullable = false)
private String description;
@Column(name = "price", nullable = false)
private BigDecimal price;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "product")
@Builder.Default
private List<Image> images = new ArrayList<>();
@Column(name = "preview_image_id")
private Long previewImageId;
@Column(name = "date_of_created")
private LocalDateTime dateOfCreated;
@PrePersist
private void init() {
dateOfCreated = LocalDateTime.now();
}
}
ProductDTO类:
package com.example.springshop.dto;
import java.math.BigDecimal;
import java.util.List;
import com.example.springshop.entity.Image;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ProductDTO {
private String title;
private String description;
private BigDecimal price;
private List<Image> images;
private Long previewImageId;
}
产品控制器:
package com.example.springshop.controllers;
import java.security.Principal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import com.example.springshop.repository.ProductRepository;
import com.example.springshop.service.ProductService;
@Controller
public class ProductController {
@Autowired
private ProductRepository productRepository;
@Autowired
private ProductService productService;
@GetMapping("/")
public String mainPage(Model model) {
model.addAttribute("products", productRepository.findAll());
return "main";
}
@GetMapping("/products/{id}")
public String productInfo(@PathVariable(value = "id") Long id, Model model) {
if (!productRepository.existsById(id)) {
return "redirect:/";
}
model.addAttribute("product", productService.findProductById(id));
return "product_info";
}
@GetMapping("/products/{id}/bucket")
public String addBucket(@PathVariable Long id, Principal principal) {
if (principal == null) {
return "redirect:/";
}
productService.addToUserBucket(id, principal.getName());
return "redirect:/";
}
}
管理控制器:
package com.example.springshop.controllers;
import java.io.IOException;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import com.example.springshop.dto.ProductDTO;
import com.example.springshop.service.ProductService;
@Controller
public class AdminController {
private final ProductService productService;
public AdminController(ProductService productService) {
this.productService = productService;
}
@GetMapping("/create_product")
public String productCreatePage() {
return "create_product";
}
@PostMapping("/create_product")
public String productCreate(@RequestParam("file1") MultipartFile file1,
@RequestParam("file2") MultipartFile file2,
@RequestParam("file3") MultipartFile file3,
ProductDTO product) throws IOException {
productService.saveProduct(product, file1, file2, file3);
return "redirect:/";
}
@GetMapping("/edit_product/{id}")
public String editProductPage(@PathVariable(value = "id") Long id, Model model) {
List<ProductDTO> result = productService.findProductById(id);
if (result == null) {
return "redirect:/";
}
model.addAttribute("product", result);
return "edit_product";
}
@PostMapping("/edit_product/{id}")
public String editProduct(ProductDTO productDTO) {
productService.editProduct(productDTO);
return "redirect:/";
}
@GetMapping("/delete_product/{id}")
public String deleteProduct(@PathVariable(value = "id") Long id) {
productService.deleteProduct(id);
return "redirect:/";
}
}
产品服务:
package com.example.springshop.service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import com.example.springshop.dto.ProductDTO;
import com.example.springshop.entity.Bucket;
import com.example.springshop.entity.Image;
import com.example.springshop.entity.Product;
import com.example.springshop.entity.User;
import com.example.springshop.mapper.ImageMapper;
import com.example.springshop.mapper.ProductMapper;
import com.example.springshop.repository.ProductRepository;
import com.example.springshop.repository.UserRepository;
import lombok.extern.slf4j.Slf4j;
@Service
@Slf4j
public class ProductService {
@Autowired
private ProductMapper productMapper;
@Autowired
private ImageMapper imageMapper;
private final ProductRepository productRepository;
private final UserRepository userRepository;
private final BucketService bucketService;
private final ImageService imageService;
public ProductService(ProductRepository productRepository, UserRepository userRepository,
BucketService bucketService, ImageService imageService) {
this.productRepository = productRepository;
this.userRepository = userRepository;
this.bucketService = bucketService;
this.imageService = imageService;
}
public List<ProductDTO> listOfProducts() {
return productMapper.fromProductList(productRepository.findAll());
}
public ProductDTO getProductById(Long id) {
return productMapper.fromProduct(productRepository.findById(id).orElse(null));
}
public void saveProduct(ProductDTO product, MultipartFile file1, MultipartFile file2, MultipartFile file3)
throws IOException {
Image image1;
Image image2;
Image image3;
if (file1.getSize() != 0) {
image1 = imageMapper.fromMultipartToImage(file1);
image1.setPreviewImage(true);
imageService.addImageToProduct(product, image1);
}
if (file2.getSize() != 0) {
image2 = imageMapper.fromMultipartToImage(file2);
imageService.addImageToProduct(product, image2);
}
if (file3.getSize() != 0) {
image3 = imageMapper.fromMultipartToImage(file3);
imageService.addImageToProduct(product, image3);
}
log.info("Saving new Product. Title: {}", product.getTitle());
Product productFromDb = productRepository.save(productMapper.toProduct(product));
productFromDb.setPreviewImageId(productFromDb.getImages().get(0).getId());
productRepository.save(productMapper.toProduct(product));
}
public List<ProductDTO> findProductById(Long id) {
List<Product> res = new ArrayList<>();
if (!productRepository.existsById(id)) {
return null;
}
Optional<Product> product = productRepository.findById(id);
product.ifPresent(res::add);
return productMapper.fromProductList(res);
}
public boolean deleteProduct(Long id) {
if (!productRepository.existsById(id)) {
return false;
}
productRepository.deleteById(id);
return true;
}
public boolean editProduct(ProductDTO productDTO) {
String title = productDTO.getTitle();
if (productRepository.findByTitle(title) == null) {
return false;
}
Product product = Product.builder()
.title(title)
.description(productDTO.getDescription())
.price(productDTO.getPrice())
.build();
productRepository.save(product);
log.info("Edit new User with title : {}", title);
return true;
}
@Transactional
public void addToUserBucket(Long productId, String username) {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new RuntimeException("User not found" + username);
}
Bucket bucket = user.getBucket();
if (bucket == null) {
Bucket newBucket = bucketService.createBucket(user, Collections.singletonList(productId));
user.setBucket(newBucket);
userRepository.save(user);
} else {
bucketService.addProducts(bucket, Collections.singletonList(productId));
}
}
}
图像服务:
package com.example.springshop.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.springshop.dto.ProductDTO;
import com.example.springshop.entity.Image;
import com.example.springshop.entity.Product;
import com.example.springshop.mapper.ProductMapper;
@Service
public class ImageService {
@Autowired
private ProductMapper productMapper;
public void addImageToProduct(ProductDTO productDTO, Image image) {
Product product = productMapper.toProduct(productDTO);
image.setProduct(product);
product.getImages().add(image);
}
}
映射器类:
package com.example.springshop.mapper;
import java.util.List;
import org.mapstruct.InheritInverseConfiguration;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import com.example.springshop.dto.ProductDTO;
import com.example.springshop.entity.Product;
@Mapper(componentModel = "spring")
public interface ProductMapper {
@Mapping(target = "id", ignore = true)
@Mapping(target = "dateOfCreated", ignore = true)
Product toProduct(ProductDTO productDTO);
@InheritInverseConfiguration
ProductDTO fromProduct(Product product);
List<Product> toProductList(List<ProductDTO> productDTOs);
List<ProductDTO> fromProductList(List<Product> products);
}
Build.gradle:
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.2'
id 'io.spring.dependency-management' version '1.1.2'
id 'com.diffplug.eclipse.apt' version '3.37.2'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '20'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa:3.1.2'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
implementation 'org.springframework.boot:spring-boot-starter-web:3.1.2'
runtimeOnly 'org.postgresql:postgresql'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-starter-security:3.1.2'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6:3.1.2.RELEASE'
implementation 'org.mapstruct:mapstruct:1.5.5.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'
implementation 'io.springfox:springfox-swagger2:3.0.0'
}
tasks.named('test') {
useJUnitPlatform()
}
我试了很多方法,但都没有用. 你能帮我看看我哪里出问题了吗?