【发布时间】:2021-11-30 14:01:15
【问题描述】:
我正在使用 JpaSpecificationExecutor 的实现,并尝试在存储库中使用 @EntityGraph 来选择他们在复杂查询中获得的关系实体。
我的实体示例(所有关系双向)
@Entity
@Table(name = "trazabilidad_contenedor")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class TrazabilidadContenedor implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "traConSeq")
@SequenceGenerator(name = "traConSeq")
private Long id;
@ManyToOne(optional = false)
@NotNull
@JsonIgnoreProperties(value = "trazabilidadContenedors", allowSetters = true)
private PromoProGesCodLer promoProGesCodeLer;
.
.
.
@Entity
@Table( name = "promo_pro_ges_cod_ler")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class PromoProGesCodLer implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@ManyToOne(optional = false)
@NotNull
@JsonIgnoreProperties(value = "promoProGesCodLers", allowSetters = true)
private ProGesCodLer procesoGestoraCodLer;
@ManyToOne(optional = false)
@NotNull
@JsonIgnoreProperties(value = "promoProGesCodLers", allowSetters = true)
private Promocion promocion;
.
.
.
@Entity
@Table(name = "promocion")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Promocion implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
.
.
.
@Entity
@Table(name = "pro_ges_cod_ler")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@NextProGesCodLer
public class ProGesCodLer implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "pgclSeq")
@SequenceGenerator(name = "pgclSeq")
private Long id;
@OneToMany(mappedBy = "procesoGestoraCodLer")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private Set<PromoProGesCodLer> promoProGesCodLers = new HashSet<>();
@ManyToOne(optional = false)
@NotNull
@JsonIgnoreProperties(value = "proGesCodLers", allowSetters = true)
private ProcesoGestora procesoGestora;
.
.
.
这是我的仓库
@Repository
public interface TrazabilidadContenedorRepository
extends JpaRepository<TrazabilidadContenedor, Long>, JpaSpecificationExecutor<TrazabilidadContenedor> {
@EntityGraph (
type = EntityGraph.EntityGraphType.FETCH,
attributePaths = {
"promoProGesCodeLer",
"promoProGesCodeLer.promocion",
"promoProGesCodeLer.promocion.direccion",
"promoProGesCodeLer.promocion.direccion.municipio",
"promoProGesCodeLer.procesoGestoraCodLer.procesoGestora",
"promoProGesCodeLer.procesoGestoraCodLer.codLER",
"promoProGesCodeLer.procesoGestoraCodLer.codLER.lerType",
"promoProGesCodeLer.procesoGestoraCodLer.nextProGesCodLer",
"promoProGesCodeLer.procesoGestoraCodLer.procesoGestora",
"promoProGesCodeLer.procesoGestoraCodLer.procesoGestora.gestora",
}
)
List<TrazabilidadContenedor> findAll(Specification<TrazabilidadContenedor> var1);
}
我的 Specification‹TrazabilidadContenedor›的构造函数
protected Specification<TrazabilidadContenedor> createSpecification(TrazabilidadContenedorCriteria criteria) {
Specification<TrazabilidadContenedor> specification = Specification.where(null);
if (criteria != null) {
if (criteria.getPromocionId() != null) {
specification =
specification.and((root, query, builder) ->
builder.equal(
root
.join(TrazabilidadContenedor_.promoProGesCodeLer, JoinType.LEFT)
.join(PromoProGesCodLer_.promocion, JoinType.LEFT)
.get(Promocion_.id),
criteria.getPromocionId()
)
);
}
if (criteria.getGestoraId() != null) {
specification =
specification.and(
(root, query, builder) ->
builder.equal(
root
.join(TrazabilidadContenedor_.promoProGesCodeLer, JoinType.LEFT)
.join(PromoProGesCodLer_.procesoGestoraCodLer, JoinType.LEFT)
.join(ProGesCodLer_.procesoGestora, JoinType.LEFT)
.join(ProcesoGestora_.gestora, JoinType.LEFT)
.get(Gestora_.id),
criteria.getGestoraId()
)
);
}
}
return specification;
}
当我只有一个条件时,criteria.getPromocionId() 或 criteria.getGestoraId() 没关系,但如果我同时使用这两个条件,我会获得。
Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list [FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=generatedAlias2,role=com.cocircular.greenadvisor.domain.PromoProGesCodLer.promocion,tableName=promocion,tableAlias=promocion2_,origin=promo_pro_ges_cod_ler promoproge1_,columns={promoproge1_.promocion_id,className=com.cocircular.greenadvisor.domain.Promocion}}] [select generatedAlias0 from com.cocircular.greenadvisor.domain.TrazabilidadContenedor as generatedAlias0 inner join generatedAlias0.promoProGesCodeLer as generatedAlias1 inner join generatedAlias1.promocion as generatedAlias2 inner join generatedAlias0.promoProGesCodeLer as generatedAlias3 inner join generatedAlias3.procesoGestoraCodLer as generatedAlias4 inner join generatedAlias4.procesoGestora as generatedAlias5 inner join generatedAlias5.gestora as generatedAlias6 where ( generatedAlias0.traceabilityStatus=:param0 ) and ( ( generatedAlias6.id=75304L ) and ( generatedAlias2.id=86754L ) )]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:138)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1542)
at org.hibernate.query.Query.getResultList(Query.java:165)
at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:76)
为此,我使用 Hibernate 5.4.15 和 Spring-Boot 2.2.7.RELEASE。
【问题讨论】:
标签: spring hibernate spring-data-jpa jhipster