gpt4 book ai didi

java - Spring Data JPA + JpaSpecificationExecutor + EntityGraph

转载 作者:IT老高 更新时间:2023-10-28 13:51:57 24 4
gpt4 key购买 nike

(使用 Spring Data JPA)我有两个实体 Parent& Child,它们之间具有 OneToMany/ManyToOne 双向关系。我添加了 @NamedEntityGraph像这样的父实体:

@Entity
@NamedEntityGraph(name = "Parent.Offspring", attributeNodes = @NamedAttributeNodes("children"))
public class Parent{
//blah blah blah

@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
Set<Child> children;

//blah blah blah
}

请注意,Parent 的 child 的获取类型是 LAZY。这是故意的。当我查询单个 parent 时,我并不总是想急切地加载 child 。通常我可以使用我的命名实体图来按需加载 child ,可以这么说。但是.....

在特定情况下,我想查询一位或多位 parent 并急切地加载他们的 child 。除此之外,我需要能够以编程方式构建此查询。 Spring Data 提供 JpaSpecificationExecutor它允许构建动态查询,但我不知道如何将它与实体图结合使用,以便在这种特定情况下急切加载子项。这甚至可能吗?是否有其他方法可以使用规范急切加载“toMany 实体”?

最佳答案

解决方案是创建实现这些功能的自定义存储库接口(interface):

@NoRepositoryBean
public interface CustomRepository<T, ID extends Serializable> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T> {

List<T> findAll(Specification<T> spec, EntityGraphType entityGraphType, String entityGraphName);
Page<T> findAll(Specification<T> spec, Pageable pageable, EntityGraphType entityGraphType, String entityGraphName);
List<T> findAll(Specification<T> spec, Sort sort, EntityGraphType entityGraphType, String entityGraphName);
T findOne(Specification<T> spec, EntityGraphType entityGraphType, String entityGraphName);

}

同时创建一个实现:

@NoRepositoryBean
public class CustomRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements CustomRepository<T, ID> {

private EntityManager em;

public CustomRepositoryImpl(Class<T> domainClass, EntityManager em) {
super(domainClass, em);
this.em = em;
}

@Override
public List<T> findAll(Specification<T> spec, EntityGraph.EntityGraphType entityGraphType, String entityGraphName) {
TypedQuery<T> query = getQuery(spec, (Sort) null);
query.setHint(entityGraphType.getKey(), em.getEntityGraph(entityGraphName));
return query.getResultList();
}

@Override
public Page<T> findAll(Specification<T> spec, Pageable pageable, EntityGraph.EntityGraphType entityGraphType, String entityGraphName) {
TypedQuery<T> query = getQuery(spec, pageable.getSort());
query.setHint(entityGraphType.getKey(), em.getEntityGraph(entityGraphName));
return readPage(query, pageable, spec);
}

@Override
public List<T> findAll(Specification<T> spec, Sort sort, EntityGraph.EntityGraphType entityGraphType, String entityGraphName) {
TypedQuery<T> query = getQuery(spec, sort);
query.setHint(entityGraphType.getKey(), em.getEntityGraph(entityGraphName));
return query.getResultList();
}

@Override
public T findOne(Specification<T> spec, EntityGraph.EntityGraphType entityGraphType, String entityGraphName) {
TypedQuery<T> query = getQuery(spec, (Sort) null);
query.setHint(entityGraphType.getKey(), em.getEntityGraph(entityGraphName));
return query.getSingleResult();
}
}

并创建一个工厂:

public class CustomRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable> extends JpaRepositoryFactoryBean<R, T, I> {

protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
return new CustomRepositoryFactory(entityManager);
}

private static class CustomRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory {

private EntityManager entityManager;

public CustomRepositoryFactory(EntityManager entityManager) {
super(entityManager);
this.entityManager = entityManager;
}

protected Object getTargetRepository(RepositoryMetadata metadata) {
return new CustomRepositoryImpl<T, I>((Class<T>) metadata.getDomainType(), entityManager);
}

protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
// The RepositoryMetadata can be safely ignored, it is used by the JpaRepositoryFactory
//to check for QueryDslJpaRepository's which is out of scope.
return CustomRepository.class;
}
}

}

并将默认存储库工厂 bean 更改为新 bean,例如在 Spring Boot 中将其添加到配置中:

@EnableJpaRepositories(
basePackages = {"your.package"},
repositoryFactoryBeanClass = CustomRepositoryFactoryBean.class
)

有关自定义存储库的更多信息:http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-behaviour-for-all-repositories

关于java - Spring Data JPA + JpaSpecificationExecutor + EntityGraph,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26291143/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com