Как написать запрос по многим ко многим ассоциативным таблицам - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть 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: Это получает каждый мастер, который имеет навык с идентификатором 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 ]

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Также вы можете рассмотреть возможность использования JpaRepository здесь:

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

}

Что это значит, что Jpa, записывая имя метода, уже отображает запрос в SQL-запрос для вашего (попробуйте, если у вас его нет)

А в конце метода «В» означает, что следует проверять не одно значение, а несколько значений

В SQL In также работает и делает что-то как:

where <condition> And <>condition And <condition> And...
0 голосов
/ 27 апреля 2018

Полагаю, проблема в том, что ваша сущность Skill действительно не имеет 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

Это должно сработать.

...