延迟加载不适用于规范

时间:2020-08-08 12:40:17

标签: java mysql hibernate jpa spring-data-jpa

我已经迁移到spring v2.1.2.RELEASE并使用了休眠版本5.3.7.FINAL

我们之间的实体之间具有@OneToOne双向关系

class Parent{

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "parent", optional = false)
    @NotAudited
    private Child child; 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
}

class Child{
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id")
    @MapsId
    @NotNull
    private Parent parent;

    @Id
    @Column(name = "indent_id", insertable = false, updatable = false)
    private Integer parentId;

}

通话

parentRepository.findByIdIn(Collections.singletonList(1));

使数据库调用为: 休眠状态:

select parent0_.id as id1_19_ from  parent parent0_ where parent0_.id in (?)

哪个工作正常,现在考虑用例,

public class Filter implements Specification<Parent> {

        @Override
        public Predicate toPredicate(Root<Indent> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
            // TODO Auto-generated method stub
            List<Integer> parentIdList = new ArrayList<>();
            parentIdList.add(1);
            ArrayList<Predicate> predicates = new ArrayList<>();
            predicates.add(root.get("id").in(parentIdList));
            return predicates.size() == 0 ? null
                    : criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));

        }

    } 



    PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.Direction.DESC, "id");
    Filter filter = new Filter();
    Page<Indent> indentPage = indentRepository.findAll(filter, pageRequest);

也可以对子实体进行数据库调用

Hibernate:
select parent0_.id as id1_19_ from  parent parent0_ where parent0_.id in (?)
select child0_.parent_id as parent_i1_29_ from child child0_ where child0_.indent_id in (?)

有什么办法可以避免Db呼叫子实体吗?

2 个答案:

答案 0 :(得分:0)

JPA提供程序通常将获取类型Lazy作为提示,因此在您的情况下,它可能根本不考虑它。检查下面

fetch公共抽象FetchType fetch(可选)定义是否将 字段或属性的值应延迟加载或必须 急切地拿来。 EAGER策略是对 持久性提供程序运行时,必须热切地获取该值。 LAZY策略是对持久性提供程序运行时的提示。如果 未指定,默认为EAGER。默认值:EAGER

JPA Doc

答案 1 :(得分:0)

您可以定义实体图以指定可传递给查询的模式,以确定要获取的属性。持久性提供程序会将图形中未包含的属性视为LAZY。

    @Entity
    @NamedEntityGraph(name = "only_id", attributeNodes={@NamedAttributeNode("id")})
    class Parent{
    
        @OneToOne(fetch = FetchType.LAZY, mappedBy = "parent", optional = false)
        @NotAudited
        private Child child; 
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer id;
    }

JPA API:

EntityGraph entityGraph = entityManager.getEntityGraph("only_idh");
// define your query
query.setHint("javax.persistence.fetchgraph",graph);

更多详细信息:https://docs.oracle.com/javaee/7/tutorial/persistence-entitygraphs002.htm

使用Spring Data JPA

 public interface MyRepository extends JpaRepository<Parent, Integer> {
 
    @EntityGraph(value = "only id")
    Parent findById(Integer id)

更多详细信息:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.entity-graph

JpaSpecificationExecutor:

public interface MyRepository extends JpaSpecificationExecutor<Parent> {
   @Override
   @EntityGraph(attributePaths = {"only_id"}, type=EntityGraphType.FETCH)
   Parent findByOne(Specification<Parent> spec);
}

更多详细信息:https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/JpaSpecificationExecutor.html

相关问题