Hibernate Fetch @Formula带注释的字段按需

时间:2018-07-25 10:13:11

标签: spring hibernate spring-boot orm hibernate-mapping

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

谢谢。

0 个答案:

没有答案