Mi lehet a probléma a MapStruct-al a Spring boot projectemben?
Mapstructal próbálok decoratort használni.
A projecten van auto component scan a packageken:
@SpringBootApplication
public class SomeApplication{
public static void main(String[] args) {
SpringApplication.run(SomeApplication.class, args);
}
}
A mappernél pedig a "spring" componentModel-t használom. Enélkül nem akar bean-t csinálni a mapper interfaceből. Manuálisan pedig nem akarok beaneket készíteni.
@Mapper(componentModel = "spring")
@DecoratedWith(CategoryMapperDecorator.class)
public interface CategoryMapper {
Category mapToCategory(CategoryDTO categoryDTO);
@Mappings({
@Mapping(target = "imageBase64", ignore = true)
})
CategoryDTO mapToCategoryDTO(Category category);
List<Category> mapToCategoryList(List<CategoryDTO> categoryDTOList);
List<CategoryDTO> mapToCategoryDTOList(List<Category> categoryList);
}
A decorator pedig így nézki:
public abstract class CategoryMapperDecorator implements CategoryMapper {
private CategoryMapper categoryMapper;
@Autowired
@Qualifier("delegate")
public void setCategoryMapper(CategoryMapper categoryMapper) {
this.categoryMapper = categoryMapper;
}
@Override
public CategoryDTO mapToCategoryDTO(Category category) {
System.out.println("Decorator is called.");
CategoryDTO categoryDTO = categoryMapper.mapToCategoryDTO(category);
setImageBase64(category, categoryDTO);
return categoryDTO;
}
private void setImageBase64(Category category, CategoryDTO categoryDTO) {
System.out.println("setImageBase64 is called");
if (category.getImage() != null) {
try {
categoryDTO.setImageBase64(category.getImage().getBase64Image());
} catch (IOException e) {
// handle the exception in some way (e.g., log an error message and return null)
System.err.println("Failed to convert image to Base64: " + e.getMessage());
}
}
}
}
A probléma az, hogy a decorator-t nem hívja meg az applikáció, így az ott adott változtatások nem jelennek meg a DTO-ban.
Az nem segít, ha a @Component annotációt rárakom az decoratorra és elvileg nem is kéne, mert a mapper interfacenél a "DecoratedWith" annotációnak létre kéne hozni a beant.
Itt vannak a generált fileok:
(Tudom a gyakori formatja nem szép, de a lényeg látszik, hogy a decoratorban lévő dolgok nincsenek benne.)
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2023-09-02T23:22:26+0200",
comments = "version: 1.5.5.Final, compiler: IncrementalProcessingEnvironment from gradle-language-java-8.1.1.jar, environment: Java 17.0.2 (Oracle Corporation)"
)
@Component
@Primary
public class CategoryMapperImpl extends CategoryMapperDecorator {
@Autowired
@Qualifier("delegate")
private CategoryMapper delegate;
@Override
public Category mapToCategory(CategoryDTO categoryDTO) {
return delegate.mapToCategory( categoryDTO );
}
@Override
public List<Category> mapToCategoryList(List<CategoryDTO> categoryDTOList) {
return delegate.mapToCategoryList( categoryDTOList );
}
@Override
public List<CategoryDTO> mapToCategoryDTOList(List<Category> categoryList) {
return delegate.mapToCategoryDTOList( categoryList );
}
}
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2023-09-02T23:22:26+0200",
comments = "version: 1.5.5.Final, compiler: IncrementalProcessingEnvironment from gradle-language-java-8.1.1.jar, environment: Java 17.0.2 (Oracle Corporation)"
)
@Component
@Qualifier("delegate")
public class CategoryMapperImpl_ implements CategoryMapper {
@Override
public Category mapToCategory(CategoryDTO categoryDTO) {
if ( categoryDTO == null ) {
return null;
}
Category.CategoryBuilder category = Category.builder();
category.id( categoryDTO.getId() );
category.childCategories( mapToCategoryList( categoryDTO.getChildCategories() ) );
category.name( categoryDTO.getName() );
category.available( categoryDTO.getAvailable() );
category.categoryTimestamp( categoryDTO.getCategoryTimestamp() );
return category.build();
}
@Override
public CategoryDTO mapToCategoryDTO(Category category) {
if ( category == null ) {
return null;
}
CategoryDTO.CategoryDTOBuilder categoryDTO = CategoryDTO.builder();
categoryDTO.id( category.getId() );
categoryDTO.name( category.getName() );
categoryDTO.childCategories( mapToCategoryDTOList( category.getChildCategories() ) );
categoryDTO.available( category.getAvailable() );
categoryDTO.categoryTimestamp( category.getCategoryTimestamp() );
return categoryDTO.build();
}
@Override
public List<Category> mapToCategoryList(List<CategoryDTO> categoryDTOList) {
if ( categoryDTOList == null ) {
return null;
}
List<Category> list = new ArrayList<Category>( categoryDTOList.size() );
for ( CategoryDTO categoryDTO : categoryDTOList ) {
list.add( mapToCategory( categoryDTO ) );
}
return list;
}
@Override
public List<CategoryDTO> mapToCategoryDTOList(List<Category> categoryList) {
if ( categoryList == null ) {
return null;
}
List<CategoryDTO> list = new ArrayList<CategoryDTO>( categoryList.size() );
for ( Category category : categoryList ) {
list.add( mapToCategoryDTO( category ) );
}
return list;
}
}
A Spring boot project amúgy Gradle-t használ. A build.gradle.kts fileban lényegében csak hozzá kell adni a függőséget, nem kell úgy szórakozni a pluginokkal, mint mavennél, ahol lombokkal kicsit macerás összehangolni, így feltételezem azzal nincs probléma.
Amúgy ezeket a függőségeket használom:
implementation("org.mapstruct:mapstruct:1.5.5.Final")
annotationProcessor("org.mapstruct:mapstruct-processor:1.5.5.Final")
Lombokra meg ezt a plugint:
id("io.freefair.lombok") version "6.5.1"
Igen, doksit olvastam. Kimásotlam belőle a megoldást és az sem működött.
Stackoverflown sem találtam megoldást.
Amúgy köszi, jó hozzáállás. A választ nem tudod, de azért ide kommentelsz valami random dolgot.
AI ezeket dobta [link]
Első tippre ezek lehetnek.
Incorrect Package Placement: If your mappers share a package with your Spring Boot Application, you may encounter the ConflictingBeanDefinitionException problem. To solve this, you can move your mappers to a different package that is not shared with your Spring Boot Application github.com.
Incorrect Use of Decorator Methods: Decorators are expected to be called only from outside the decorated mapper. If you split up your mapper into two mappers, it should work github.com.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!