Mapstruct不使用龙目岛定义的构建器



解决方案:

我不得不更改mapstructlombokannotationProcessorPaths的顺序.

我不得不把mapstruct放在lombok上面,然后它起作用了。

我将下面的pom更新为工作版本,因此这里没有非工作代码。

我还将龙目岛版本转换回当前版本,而不是使用边缘版本。


原始问题:

我有 2 组或多或少相同的类(见下面的示例(

  • 一组是我的API的DTO,我希望使用龙目岛的@Value和@Builder不可变
  • 一组是将存储在数据库中的实体。与龙目岛的@Data

最初,我将项目设置为使用:

  • 龙目岛 1.18.12
  • 映射结构 1.3.1
  • 爪哇 11
  • 马文

我找到了龙目岛的文档,解释了如何将注释处理器添加到 maven 插件中 https://projectlombok.org/setup/maven

但是在执行时,我仍然会得到Error:(16,25) java: ClassX does not have an accessible parameterless constructor.

搜索此消息,我发现了大约 2 到 3 年的问题,但没有最新的问题。我还看到,这些帖子的问题已得到解决。

在至少一个帖子中提到,在将项目拆分为模块时,它起作用了。这对我也有用。当我将 DTO 移动到另一个 maven 模块时,在那里构建它们并设置它工作的依赖项,但这绝对不是我想要的项目结构。另外,因为我可能还需要将我的实体移出,并且我不想为我正在创建的每个 Pojo 结构创建一个新模块。

我还在龙目岛边缘版本上找到了那篇帖子: https://projectlombok.org/download-edge 更改列表中的第二点是

重大更改:MAPSTRUCT用户现在应该将依赖项添加到lombok-mapstruct-binding。这解决了使用 lombok(和 mapstruct(编译模块的问题。

所以我也试过了。 我将存储库添加到我的pom中,添加了lombok-mapstruct-binding并将lombok版本设置为edge-SNAPSHOT

。但即使在清理之后,编译步骤也会失败。


在这两者之间,我也更改了我的 DTO 以使用@Data,但我想把它改回来。

最后,这里有一些代码示例和详细信息。

DTO

@Data
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = BDto.class, name = "b"),
@JsonSubTypes.Type(value = CDto.class, name = "c")
})
public abstract class ADto {
private long id;
private String type;
private Set<String> metadata;
private Set<String> tags;
}
@Data
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class BDto extends ADto {
private String path;
@Builder
private BDto(long id, String path, Set<String> metadata, Set<String> tags) {
super(id, "b", metadata, tags);
this.path = path;
}
}
@Data
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class CDto extends ADto {
private String name;
private Set<A> collection;
@Builder
private CDto(long id, String name, Set<A> collection, Set<String> metadata, Set<String> tags) {
super(id, "c", metadata, tags);
this.collection = collection;
this.name = name;
}
}

实体

@Entity
@Table
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type")
@AllArgsConstructor
@NoArgsConstructor
@Getter
public abstract class A extends PanacheEntityBase {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected long id;
@Column(name = "type", insertable = false, updatable = false)
private String type;
/* ... */
}
@Entity
@DiscriminatorValue("b")
@NoArgsConstructor
@Getter
@ToString
public class B extends A {
public B(long id, String path, Set<String> metadata, Set<Tag> tags) {
super(id, "b", metadata, tags);
this.path = path;
}
public B(String path) {
super(0, "b", new HashSet<>(), new HashSet<>());
this.path = path;
}
@Column(name = "path")
@Setter
private String path;
}
@Entity
@DiscriminatorValue("c")
@NoArgsConstructor
@Getter
public class C extends A {
public C(long id, String name, List<A> collection, Set<String> metadata, Set<Tag> tags) {
super(id, "c", metadata, tags);
this.collection = collection;
this.name = name;
}
@Column(name = "name")
private String name;
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "c_id")
@OrderBy("order")
List<A> collection;
}

映射器

public interface AMapper {
default String tagToDto(Tag tag) {
return tag.getTag();
}
default Tag tagFromDto(String tag) {
return Tag.createIfNotExists(tag);
}
}
@Mapper()
public interface BMapper extends AMapper {
@Override
@Mapping(target = "tags",
qualifiedByName = "tagToDto")
BDto toDto(B b);
@Override
@Mapping(target = "tags",
qualifiedByName = "tagToEntity")
B toEntity(BDto b);
}
@Mapper()
public interface CMapper extends AMapper {
@Override
@Mapping(target = "tags",
qualifiedByName = "tagToDto")
CDto toDto(C b);
@Override
@Mapping(target = "tags",
qualifiedByName = "tagToEntity")
C toEntity(CDto b);
}

聚 甲醛

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<artifactId>dummy</artifactId>
<groupId>dummy</groupId>
<version>0.1.0</version>
<packaging>pom</packaging>
<properties>
<compiler-plugin.version>3.8.1</compiler-plugin.version>
<maven.compiler.parameters>true</maven.compiler.parameters>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<lombok.version>1.18.12</lombok.version>
<mapstruct.version>1.3.1.Final</mapstruct.version>
</properties>
<repositories>
<repository>
<id>projectlombok.org</id>
<url>https://projectlombok.org/edge-releases</url>
</repository>
</repositories>
<dependencies>
<!-- other stuff -->
<!-- Tools -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<!-- <scope>provided</scope> -->
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<annotationProcessorPaths>
<annotationProcessorPath>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</annotationProcessorPath>
<annotationProcessorPath>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>

使用龙目岛(1.18.18(和mapstruct(1.4.2.Final(,在我之后一切都可以正常工作:

  1. 添加了插件lombok-mapstruct-binding
  2. 将 Lombok-mapstruct-binding 添加到插件maven-compiler-pluginannotationProcessorPaths部分

链接:

  • GitHub示例pom.xml:https://github.com/mapstruct/mapstruct-examples/blob/master/mapstruct-lombok/pom.xml
  • 从 https://mapstruct.org/faq/:If you are using Lombok 1.18.16 or newer you also need to add lombok-mapstruct-binding in order to make Lombok and MapStruct work together.

最新更新