首页 > 解决方案 > Hibernate 按需获取 @Formula 注释字段

问题描述

我有一个实体(以 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 类型也无济于事。

谢谢是提前。

标签: springhibernatespring-bootormhibernate-mapping

解决方案


推荐阅读