java - 在 MapStruct 中使用qualifiedBy 或qualifiedByName 参数不起作用
问题描述
我有几个实体
- 邮政
public class Post {
@Id
@SequenceGenerator(name = "jpaSequence.Post",
sequenceName = "SEQUENCE_POST",
allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "jpaSequence.Post")
private Long id;
private String subject;
@OneToMany(mappedBy = "post", fetch = FetchType.LAZY)
private List<Comment> comments = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn
private User user;
- 评论
@Entity
@Table(name = "comments")
public class Comment {
@Id
@SequenceGenerator(name = "jpaSequence.Comment",
sequenceName = "SEQUENCE_COMMENT",
allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "jpaSequence.Comment")
private Long id;
private String reply;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn
private Post post;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn
private User user;
- 用户
@Entity
@Table(name = "users")
public class User {
@Id
@SequenceGenerator(name = "jpaSequence.User",
sequenceName = "SEQUENCE_USER",
allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "jpaSequence.User")
private Long id;
private String name;
private String email;
- 邮递到
public class PostDto {
private Long id;
private String subject;
private List<CommentDto> comments = new ArrayList<>();
private UserDto user;
- 评论Dto
public class CommentDto {
private Long id;
private String reply;
private PostDto post;
private UserDto user;
- 用户Dto
public class UserDto {
private Long id;
private String name;
private String email;
- 映射器
@Mapper(componentModel = "spring")
public interface PostMapper {
Post postDtoToPostEntity(PostDto dto);
@Mapping(target = "post.comments", ignore = true)
CommentDto toCommentDto(Comment entity);
@Mapping(target = "comments", source = "entity.comments", qualifiedBy = CommentListDtoAnnotation.class)
PostDto postEntityToPostDto(Post entity);
@CommentListDtoAnnotation
default Iterable<CommentDto> commentListEntityToCommentListDto(Iterable<Comment> source) {
Iterable<CommentDto> collect = StreamSupport.stream(source.spliterator(), false)
.map(this::toCommentDto)
.peek(dto -> dto.setPost(null))
.collect(Collectors.toList());
return collect;
}
Iterable<Post> postListDtoToPostListEntity(Iterable<PostDto> list);
Iterable<PostDto> postListEntityToPostListDto(Iterable<Post> list);
}
- 评论映射器
@Mapper(componentModel = "spring")
public interface CommentMapper {
Comment commentDtoToCommentEntity (CommentDto dto);
@Mapping(target = "post.comments", ignore = true)
CommentDto commentEntityToCommentDto(Comment entity);
Iterable<Comment> commentListDtoToCommentListEntity(Iterable<CommentDto> list);
Iterable<CommentDto> commentListEntityToCommentListDto(Iterable<Comment> list);
}
- 注解
import org.mapstruct.Qualifier;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface CommentListDtoAnnotation {
}
但是当映射发生时,我得到以下响应:
{
"id": 1,
"subject": "JPA Entity Graph In Action",
"comments": [
{
"id": 1,
"reply": "Nice !!",
"post": {
"id": 1,
"subject": "JPA Entity Graph In Action",
"comments": [],
"user": {
"id": 1,
"name": "user1",
"email": "user1@test.com"
}
},
"user": {
"id": 2,
"name": "user2",
"email": "user2@test.com"
}
},
{
"id": 2,
"reply": "Cool !!",
"post": {
"id": 1,
"subject": "JPA Entity Graph In Action",
"comments": [],
"user": {
"id": 1,
"name": "user1",
"email": "user1@test.com"
}
},
"user": {
"id": 3,
"name": "user3",
"email": "user3@test.com"
}
}
],
"user": {
"id": 1,
"name": "user1",
"email": "user1@test.com"
}
}
更新_1
- 服务
@Service
public class PostReadServiceImpl implements PostReadService {
private PostRepository repository;
private PostWithoutNestedLevelsTransformers transformer;
@Autowired
public PostReadServiceImpl(PostRepository repository,
PostWithoutNestedLevelsTransformers transformer) {
this.repository = repository;
this.transformer = transformer;
}
@Override
public PostDto getEntryById(Long id) {
Post entity = findEntry(id);
PostDto postDto = this.transformer.transformEntityToDto(entity);
return postDto;
}
private Post findEntry(Long id) {
return this.repository.findById(id).orElseThrow(() -> new RuntimeException("Post not found!"));
}
@Transactional
@Override
public Iterable<PostDto> getListPosts() {
Iterable<Post> posts = findListPosts();
Iterable<PostDto> postDtoList = this.transformer.transformListEntityToDtoList(posts);
return postDtoList;
}
private Iterable<Post> findListPosts() {
Iterable<Post> posts = this.repository.findAll();
return posts;
}
private Iterable<Comment> pickUpComment (List<Comment> comments ) {
List<Comment> listComment = new ArrayList<>();
for (Comment comment : comments) {
Comment conversionComment = moveData(comment);
listComment.add(conversionComment);
}
return listComment;
}
private Comment moveData(Comment comment) {
Comment conversionComment = new Comment();
String commentReply = comment.getReply();
Long idUser = comment.getId();
conversionComment.setId(idUser);
conversionComment.setReply(commentReply);
return conversionComment;
}
}
- 变压器
@Component
public class PostTransformer {
private PostMapper mapper;
@Autowired
public PostTransformer(PostMapper mapper) {
this.mapper = mapper;
}
public PostDto transformEntityToDto(Post entity) {
PostDto postDto = this.mapper.postEntityToPostDto(entity);
return postDto;
}
public Post transformDtoToEntity(PostDto dto) {
return this.mapper.postDtoToPostEntity(dto);
}
public Iterable<PostDto> transformListEntityToDtoList(Iterable<Post> listEntity) {
Iterable<PostDto> postDtoList = this.mapper.postListEntityToPostListDto(listEntity);
return postDtoList;
}
public Iterable<Post> transformListDtoToEntityList(Iterable<PostDto> listDto) {
return this.mapper.postListDtoToPostListEntity(listDto);
}
}
该方法必须执行:
@CommentListDtoAnnotation
default Iterable<CommentDto> commentListEntityToCommentListDto(Iterable<Comment> source) {
但事实并非如此。
在字段注释中,嵌套字段 - 帖子 - 必须为空...
我不明白我做错了什么。
解决方案
推荐阅读
- ios - 如何返回实现另一个协议的泛型类型
- java - Android:如何找出内部存储中有多少个文件?
- azure - 尝试在 azure devops 中克隆管道时遇到授权问题
- android - docker - android主机上的连接被拒绝
- c++ - 如果条件不相关,我应该更喜欢两个 if 语句而不是 if-else 语句吗?
- java - 如何为自定义对话框设置圆角?
- html - BOT 用户会话在网络频道中重叠
- discord.js - 不知道如何保护命令免受没有角色 Discord.js 的人的影响
- css - CSS -webkit-tap-highlight-color: 透明;有可访问性影响吗?
- node.js - CosmosDB - 在第 3 方主机上运行应用程序时连接