使用Querydsl获取@ElementCollection条目

时间:2015-04-23 19:43:59

标签: jpa querydsl

我有一个@Entity类,它包含一个@ElementCollection:

@Entity
public class Skill extends JpaEntity {
  @ElementCollection(targetClass = SkillName.class)
  @CollectionTable(joinColumns = @JoinColumn(name = "SKILL_ID"))
  private Set<SkillName> names = new HashSet<>();
...

这些元素是在没有ID的嵌套@Embeddable类中定义的:

  @Embeddable
  @Immutable
  @Table(uniqueConstraints = @UniqueConstraint(columnNames = "NAME"))
  public static class SkillName extends ValueObject {
    private boolean selectable;
    @Column(unique = true, nullable = false)
    @Size(max = 64)
    @NotEmpty
    private String name;
...

我尝试通过Querydsl获取该元素集合的一些特定元素:

    QSkill skill = QSkill.skill;
    QSkill_SkillName skillName = QSkill_SkillName.skillName;

    List<SkillName> foundSkillNames = from(skill)
    .innerJoin(skill.names, skillName).where(...)
    .list(skillName);

这给了我一个MySQLSyntaxErrorException:Unknown column&#39; names1_.id&#39;在&#39;字段列表&#39;因为生成的查询看起来像:

select names1_.id as col_0_0_ from Skill skill0_ inner join Skill_names names1_ on ...

这显然是错误的,因为SkillName没有id

如果我用.list(skillName.name)替换.list(skillName),一切正常,但我得到一个字符串列表而不是一个SkillNames列表。

所以问题是: 如何通过Querydsl获取@ElementCollection的@Embeddables列表?

2 个答案:

答案 0 :(得分:2)

因为您在实体中寻找可嵌入对象,所以您可以从实体导航到请求的Embeddable(在您的情况下为“SkillName”) - 因此您的查询应该更改为list(技能) - 实体:

List<Skill> list = 
    from(skill).innerJoin(skill.names, skillName).
    where(skillName.name.like(str)).
    list(skill);

for (Skill skill : list) {
  // do something with 
  Set<SkillNames> skillNames = skill.getNames();
}

HTH

答案 1 :(得分:1)

您无法直接投影Embeddable实例,但也可以使用

  • Projections.bean(SkillName.class, ...)填充或
  • Projections.tuple(...)将skillName属性作为元组实例获取