【问题标题】:How to write query on many to many association table如何在多对多关联表上编写查询
【发布时间】:2018-10-07 22:15:08
【问题描述】:

我有 2 个实体,它们之间存在多对多关系。我想在关联表上写一个查询。

Here are the two entities. Craftsmen and Skill.
I want to write a query which selects all Craftsmen with a given skill. 

    @Entity
    @Table(name = "craftsman")
    public class Craftsman {

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

        @ManyToMany
        @JoinTable(name = "craftman_skill", joinColumns = @JoinColumn(name = "craftman_id", referencedColumnName = "id"), 
            inverseJoinColumns = @JoinColumn(name = "skill_id", referencedColumnName = "id"))
        private List<Skill> skillList;
    }
        @Entity
        @Table(name = "skill")
        public class Skill {
            @ManyToMany(mappedBy = "skillList")
            @JsonBackReference
            private List<Craftsman> craftmanList;
        }

这是我尝试过的:

@Query("SELECT c FROM Craftsman c JOIN c.skillList sl WHERE c.skillList.skill_id = :skillId")
    public List<Craftsman> getCraftsmanBySkill(@Param("skillId") Long skillId);

这是在 MySql 中工作的查询: 这将获取所有具有 id 1 技能的工匠:

select c.name from craftsman c, craftman_skill cs 
where cs.craftman_id = c.id 
and cs.skill_id = 1;

这是我得到的错误:

Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryException: could not resolve property: skill_id of: com.craftsmen.crafts.persistence.Skill [SELECT c FROM com.craftsmen.crafts.persistence.Craftsman c JOIN c.skillList sl WHERE c.skillList.skill_id = :skillId ]
Caused by: org.hibernate.QueryException: could not resolve property: skill_id of: com.craftsmen.crafts.persistence.Skill [SELECT c FROM com.craftsmen.crafts.persistence.Craftsman c JOIN c.skillList sl WHERE c.skillList.skill_id = :skillId ]

【问题讨论】:

  • c.skillList.skill_id 想做什么?你已经加入了!为什么不直接做s1.id ?!!这是 JPQL,也不是 SQL
  • Skill 有一个 id 我只是没有发布是偶然的。

标签: java sql hibernate spring-boot jpa


【解决方案1】:

我想问题是,您的 Skill 实体确实没有技能 ID,或者更好的是 id

您是否尝试为您的Skill 实体提供id

@Entity
@Table(name = "skill")
public class Skill {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;

   @ManyToMany(mappedBy = "skillList")
   @JsonBackReference
   private List<Craftsman> craftmanList;
}

在您的 Craftsman 实体中引用它

@Entity
@Table(name = "craftsman")
public class Craftsman {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToMany
    @JoinTable(name = "craftman_skill", joinColumns = @JoinColumn(name = "craftman_id", referencedColumnName = "id"), 
        inverseJoinColumns = @JoinColumn(name = "skill_id", referencedColumnName = "id"))
    private List<Skill> skillList;
}

然后将Query改为

SELECT c FROM Craftsman c JOIN c.skillList sl WHERE sl.id = :skillId

这应该可以解决问题。

【讨论】:

    【解决方案2】:

    您也可以在这里考虑使用 JpaRepository 的选项:

    public interface CraftsmanRepository extends JpaRepository<Craftsman, String> {
        public List<Craftsman> getBySkillListIn(@NotEmpty List<Skill> skillList);
    

    }

    这意味着,Jpa 通过编写方法名称已经将查询映射到您的 SQL 查询(如果没有,请尝试)

    在方法的末尾,“In”意味着它应该检查的不是一个值,而是多个值

    在 SQL 中 In 也可以工作并执行以下操作:

    where <condition> And <>condition And <condition> And...
    

    【讨论】:

      猜你喜欢
      • 2011-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多