Querydsl: 左连接与 leftJoin(target).on(condition) 抛出“希望加入的路径!” 错误

创建于 2016-01-14  ·  8评论  ·  资料来源: querydsl/querydsl

你好,

我想用leftJoin(EntityPath<P> target).on(Predicate condition)符号执行左连接。

这是我的实体:

@Entity(name = "CLASSROOM")
public class Classroom {
    // [...]
}

@Entity(name = "STUDENT")
public class Student {

    @Column(name = "NAME")
    private String name;

    <strong i="9">@ManyToOne</strong>
    @JoinColumn(name = "CLASSROOM_ID")
    private Classroom classroom;

    // [...]
}

这是一个不起作用的示例查询:

QClassroom classroom = QClassroom.classroom;
QStudent student = QStudent.student;

query.from(classroom)
    .leftJoin(student).on(classroom.eq(student.classroom))
    .where(student.name.eq("antoine"))
    .list(classroom)

这是错误日志:

org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join! [select classroom
from com.my.personnal.path.entity.Classroom classroom
  left join STUDENT student with classroom = student.classroom
where student.name = ?1]

当然,对于这个例子,我可以做这样的事情:

query.from(student)
    .leftJoin(student.classroom, classroom)
    .where(student.name.eq("antoine"))
    .list(classroom)

...但我真正的查询比这更大,我不能以query.from(student)开始查询。

我做错了什么?

我正在使用 QueryDsl 3.6.6

resolved

所有8条评论

它应该是

QClassroom classroom = QClassroom.classroom;
QStudent student = QStudent.student;

query.from(classroom)
    .leftJoin(classroom.students, student)
    .where(student.name.eq("antoine"))
    .list(classroom)

为此,您需要在课堂上逆向映射学生

好的,谢谢,这可能是一个解决方案,但实际上我有两个限制:

  • .from(classroom)开始我的查询
  • 将两个实体与Student实体中的ManyToOne关联链接起来(没有双向关联)

有了这两个限制,是否有可能加入我的两个实体?

这也应该有效

query.from(student, classroom)
    .where(
        student.classroom.eq(classroom),
        student.name.eq("antoine"))
    .list(classroom)

如果还没有解决,请重新打开

嗨蒂莫,

抱歉重新打开这个问题,但我有一个类似的问题,无法接受你上面描述的解决方案。

我的架构:
校园班

<strong i="9">@Entity</strong>
public class Campus {

<strong i="10">@Id</strong>
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String name;

@OneToMany(mappedBy = "associatedCampus", cascade = CascadeType.ALL)
private Set<Building> buildings;

... Getters/Setters, Constructors

建筑类

<strong i="14">@Entity</strong>
public class Building {

<strong i="15">@Id</strong>
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
private String uuid;

<strong i="16">@ManyToOne</strong>
@JoinColumn(name = "associatedCampus")
private Campus associatedCampus;

... Getters/Setters, Constructors

我尝试从 Campus 表加入到 Building 表,但总是遇到我不明白的错误。
错误:java.lang.IllegalArgumentException:building.associatedCampus 不是根路径

从大楼到校园加入绝对没有问题,但从校园到大楼则不然。
例子:

public List<Building> getBuildingsByCampusName(String campusName) {
  JPAQuery<Building> query = new JPAQuery<>(em);
  QCampus campus = QCampus.campus;
  QBuilding building = QBuilding.building;
  query.select(building)
  .from(building)
  .join(building.associatedCampus, campus)
  .where(campus.name.like("%" + campusName + "%"));
  List<Building> result = query.fetch();
  return result;

你能不能给我一个提示,我的问题是什么,或者为什么建筑->校园的反向连接不起作用?

格雷茨
马库斯

我的实体如下:
@实体
@Table(name = "参与者")
公共类参与者{
@OneToOne(cascade = CascadeType.DETACH, fetch = FetchType.EAGER, targetEntity = ServiceType.class)
@JoinTable(name = "PARTICIPANT_SERVICES", joinColumns = @JoinColumn(name = "PARTICIPANT_ID", referencedColumnName = "PARTICIPANT_ID"), inverseJoinColumns = @JoinColumn(name = "SERVICE_TYPE_ID",referencedColumnName = "SERVICE_TYPE_ID"))
私人名单服务类型;

    @OneToMany(mappedBy = "participant")
@Cascade({org.hibernate.annotations.CascadeType.ALL})
private List<ParticipantRegionCountry> participantRegionCountries;

吸气剂 / 吸气剂
}

@实体
@Table(name = "SERVICE_TYPE")
公共类服务类型{

<strong i="20">@Id</strong>
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "SERVICE_TYPE_ID")
private Long id;

@Column(name = "SERVICE_TYPE_NAME")
private String name;
   getter / setter

}
当我在参与者实体上查询异常时:
列表参与者 = 新的 ArrayList<>();

    JPQLQuery<Participant> query = new JPAQuery<>(em);
    QParticipant participant = QParticipant.participant;
    QParticipantRegionCountry participantRegionCountry = QParticipantRegionCountry.participantRegionCountry;
    BooleanBuilder predicate = new BooleanBuilder();
    predicate.and(participantRegionCountry.region.in(regions));

    participants = query.select(participant).from(participant).join(participant.participantRegionCountries, participantRegionCountry).where(predicate).distinct().fetch();

例外:
休眠:选择不同participan0_.PARTICIPANT_ID如PARTICIPANT_ID1_6_,participan0_.BUSINESS_NAME如BUSINESS_NAME2_6_,participan0_.BUSINESS_TYPE_ID如BUSINESS_TYPE_ID9_6_,participan0_.CITY_ID如CITY_ID10_6_,participan0_.CONTACT_ADDRESS如CONTACT_ADDRESS3_6_,participan0_.CONTACT_EMAIL如CONTACT_EMAIL4_6_,participan0_.CONTACT_NAME如CONTACT_NAME5_6_,participan0_.CONTACT_PHONE如CONTACT_PHONE6_6_,participan0_.COUNTRY_ID为COUNTRY_ID11_6_,participan0_.CURRENCY_ID为CURRENCY_ID12_6_,participan0_.LANGUAGE_ID为LANGUAGE_ID13_6_,participan0_.PARTICIPANT_PACK_ID为PARTICIPANT_PACK_14_6_,participan0_.PARTICIPANT_TYPE_ID为PARTICIPANT_TYPE_15_6_,participan0_.PAYMENT_METHOD_TYPE_ID为PAYMENT_METHOD_TY16_6_,participan0_.PROJECTED_VOLUME为PROJECTED_VOLUME7_6_,participan0_.REGION_ID为REGION_ID17_6_, participan0_.USER_NAME as USER_NAME8_6_, participan0_1_.SERVICE_TYPE_ID as SERVICE_TYPE_ID1_12_ from PARTICIPANT participan0_left external join PARTICIPANT_SERVICES par ticipan0_1_ on participan0_.PARTICIPANT_ID=participan0_1_.PARTICIPANT_ID 内连接 SERVICE_TYPE servicetyp1_ on participan0_1_.SERVICE_TYPE_ID=servicetyp1_.SERVICE_TYPE_ID 内连接 PARTICIPANT_REGION_COUNTRY participan2_ 上 participan0_.PARTICIPANT_REGION_COUNTRY participan2_在 participan02_service_TYPE_PARTICIPANT_PARTICIPANT_COUNTRY participan2_ 上 service_TYPE_PARTICIPANT_ID_PARTICIPANT_TYPE_PARTICIPANT_ID_PARTICIPANT_TYPE_PARTICIPANT_ 和 (participan2_.REGION_ID in (? , ?))
休眠:选择 servicetyp0_.SERVICE_TYPE_ID 作为 SERVICE_TYPE_ID1_18_0_, servicetyp0_.SERVICE_TYPE_NAME 作为 SERVICE_TYPE_NAME2_18_0_ from SERVICE_TYPE servicetyp0_ where servicetyp0_.SERVICE_TYPE_ID=?
javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: 无法设置字段值 [com.mycompany.app.spring.orm.model。 ServiceType@4e9e0c6 ] 反射值:[class com.mycompany.app.spring.orm.model.Participant.serviceTypes] com.mycompany.app.spring.orm.model.Participant.serviceTypes 的设置者
在 org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:149)
在 org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:157)
在 org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1423)
在 org.hibernate.query.Query.getResultList(Query.java:146)
在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
在 java.lang.reflect.Method.invoke(Method.java:497)
在 org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:379)
在 com.sun.proxy.$Proxy47.getResultList(来源不明)
在 com.querydsl.jpa.impl.AbstractJPAQuery.getResultList(AbstractJPAQuery.java:160)
在 com.querydsl.jpa.impl.AbstractJPAQuery.fetch(AbstractJPAQuery.java:202)
在 com.mycompany.app.spring.orm.service.ParticipantService.listParticipants(ParticipantService.java:53)
在 com.mycompany.app.App.main(App.java:56)
引起:org.hibernate.PropertyAccessException:无法设置字段值 [com.mycompany.app.spring.orm.model。 ServiceType@4e9e0c6 ] 反射值:[class com.mycompany.app.spring.orm.model.Participant.serviceTypes] com.mycompany.app.spring.orm.model.Participant.serviceTypes 的设置者
在 org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:61)
在 org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:649)
在 org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:205)
在 org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:4711)
在 org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:183)
在 org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:125)
在 org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1152)
在 org.hibernate.loader.Loader.processResultSet(Loader.java:1011)
在 org.hibernate.loader.Loader.doQuery(Loader.java:949)
在 org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341)
在 org.hibernate.loader.Loader.doList(Loader.java:2692)
在 org.hibernate.loader.Loader.doList(Loader.java:2675)
在 org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2507)
在 org.hibernate.loader.Loader.list(Loader.java:2502)
在 org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:502)
在 org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:392)
在 org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216)
在 org.hibernate.internal.SessionImpl.list(SessionImpl.java:1490)
在 org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1445)
在 org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1414)
……还有 11 个
引起:java.lang.IllegalArgumentException:无法将 java.util.List 字段 com.mycompany.app.spring.orm.model.Participant.serviceTypes 设置为 com.mycompany.app.spring.orm.model.ServiceType
在 sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
在 sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
在 sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
在 java.lang.reflect.Field.set(Field.java:764)
在 org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:41)
... 30 多个
有什么解决办法吗?
我是 QueryDSL 的新手,但为什么要查询 service_types?

那么自连接应该如何工作?

在这种情况下肯定没有定义任何关系。

JPQL 是基于属性的,因此如果没有关系(定义为属性),那么您就不能真正随意地加入它。
除非你去JpaSqlQuery,在那里你可以使用更多的SQL。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

heesuk-ahn picture heesuk-ahn  ·  5评论

intuitiveminds picture intuitiveminds  ·  8评论

okihouse picture okihouse  ·  5评论

pascal-hofmann picture pascal-hofmann  ·  4评论

devcken picture devcken  ·  6评论