我有一个实体(用2种方式声明)(为了可读性,省略了一些不影响代码的部分)
实体版本1。
@Entity
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Formula("(SELECT COUNT(w.id) FROM stock s LEFT JOIN warehouse w ON s.id=w.stock_id WHERE s.article_id = id)")
private int variants;
public int getVariants() {
return variants;
}
}
实体版本2。
@Entity
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Transient
private int variants;
@Access(AccessType.PROPERTY)
@Formula("(SELECT COUNT(w.id) FROM stock s LEFT JOIN warehouse w ON s.id=w.stock_id WHERE s.article_id = id)")
public int getVariants() {
return variants;
}
}
分别的DTO和ArticleMapper-MapStruct
@JsonIgnoreProperties(ignoreUnknown = true)
public class ArticleDTOCommon {
private Long id;
private String name;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class ArticleDTO {
private Long id;
private String name;
private int variants;
}
@Mapper(componentModel = "spring", uses = {})
public interface ArticleMapper{
ArticleDTO toDto(Article article);
ArticleDTOCommon toDtoCommon(Article article);
}
我有一个@Service层,据我所知Hibernate在其上创建它的代理(用于定义要获取或不获取哪个字段)并进行交易。
@Service
@Transactional
public class ArticleService {
@Transactional(readOnly = true)
public List<ArticleDTO> findAll() {
return articleRepository.findAll()
stream().map(articleMapper::toDto).collect(Collectors.toList());
}
@Transactional(readOnly = true)
public List<ArticleDTO> findAllCommon() {
return articleRepository.findAll()
stream().map(articleMapper::toDtoCommon).collect(Collectors.toList());
}
}
它在获取关联实体时可以正常工作,但是 问题是(正在获取@Formula带注释的字段),当我在日志中查找已执行的查询时,它会获取所有时变类型的@Formula带注释的查询,而不取决于各自的DTO。 但是必须在toDtoCommon上将其忽略-即它一定不能获取变体字段->因为在将Article映射到ArticleDtoCommon时,它不使用Article的getVariant()字段。如上所述,我已经尝试了多种方法。
我可以通过编写本机查询(针对findAllCommon()方法)来解决它,并通过其他方式分别映射...但是我想知道我们如何使用ORM方法来解决它以及问题出在哪里。 操纵@Access类型也无济于事。
谢谢。