2015-06-25 3 views
0

Я искал форумы и всюду для однонаправленного запроса manyToMany. Я нахожу много примеров, но я не могу приспособить их к своим потребностям :(JPQL manyToMany однонаправленный запрос

У меня есть 2 классов сущностей (аниме & Пользователь)

Anime { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "anime_id") 
    private Integer id; 

    //Other fields etc. 
} 

User { 
    @Id 
    @ValidUsername 
    @Column(name = "user_id") 
    private String username; 

    @ManyToMany() 
    @JoinTable(name = "users_animes", 
     joinColumns = @JoinColumn(name = "anime_id", referencedColumnName =  "anime_id"), 
     inverseJoinColumns = @JoinColumn(name = "user_id", referencedColumnName = "user_id")) 
    private final List<Anime> animes = new ArrayList<>(); 
} 

Аниме просто хранит данные из аниме. Пользователь имеет имя пользователя и т. д. пользователя и список аниме, на который он подписался.

Теперь я пытаюсь найти запрос, который позволит мне получить все аниме в этом списке. Он отображается в таблице как «users_animes "

Было бы огромной помощью, так как я довольно новичок в JPQL.

Спасибо!

ответ

0

Вот простой пример. Давайте предположим, что у нас есть Страна Entity, которая может иметь несколько граждан:

@Entity 
@Table (name = "countries") 
public class Country implements Serializable { 

    @Id 
    @Column (name = "coun_id") 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

    @Column (name = "country_name") 
    private String countryName; 

    @ManyToMany (cascade = CascadeType.ALL) 
    @JoinTable (
      name = "citizen_country", 
      joinColumns = @JoinColumn (name = "country_id", referencedColumnName = "coun_id"), 
      inverseJoinColumns = @JoinColumn (name = "citizen_id", referencedColumnName = "cit_id") 
    ) 
    private List<Citizen> citizens; 

    public Country() {} 
    public Country(String countryName) { 
     this.countryName = countryName; 
    } 
    //getters and setters 
} 

И гражданин, который может принадлежать нескольким странам:

@Entity 
@Table (name = "citizens") 
public class Citizen implements Serializable { 

    @Id 
    @Column (name = "cit_id") 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

    @Column (name = "country_name") 
    private String citizenName; 

    public Citizen() {} 

    public Citizen(String citizenName) { 
     this.citizenName = citizenName; 
    } 

    public void setId(Long id) { this.id = id; } 
    public Long getId() { return id; } 

    public void setCitizenName(String citizenName) { this.citizenName = citizenName; } 
    public String getCitizenName() { return citizenName; } 

    //getters and setters 
} 

Это однонаправленный, так же, как вы хотели, чтобы это было. Таким образом, Citizen Entity не знает о стране, поэтому вы не можете напрямую получать информацию о том, в какой стране принадлежит определенный гражданин. Однако вы можете получить информацию о том, какие граждане принадлежат определенной стране.

Двигаясь дальше, вы можете заполнить ваши таблицы:

Citizen citizen1 = new Citizen("Smith"); 
    Citizen citizen2 = new Citizen("Kowalski"); 
    Citizen citizen3 = new Citizen("Muller"); 
    dataAccess.saveCitizen(citizen1); 
    dataAccess.saveCitizen(citizen2); 
    dataAccess.saveCitizen(citizen3); 

    // now let's fetch them from DB, along with their other properties (only id in this case) 
    citizen1 = dataAccess.getCitizenByName("Smith"); 
    citizen2 = dataAccess.getCitizenByName("Kowalski"); 
    citizen3 = dataAccess.getCitizenByName("Muller"); 

    Country country1 = new Country("Foo"); 
    Country country2 = new Country("Bar"); 

    // create lists to hold citizens for each country 
    List<Citizen> citizenList1 = new ArrayList(); 
    List<Citizen> citizenList2 = new ArrayList(); 

    // add elements to the lists 
    citizenList1.add(citizen1); 
    citizenList1.add(citizen2);   
    citizenList2.add(citizen2); 
    citizenList2.add(citizen3); 

    //assign lists of citizens to each country 
    country1.setCitizens(citizenList1); 
    country2.setCitizens(citizenList2); 

    //save data in DB 
    dataAccess.saveCountry(country1); 
    dataAccess.saveCountry(country2); 

    //fetch list of all persisted countries (associated Citizens will come along) 
    countries = dataAccess.getAllCountries(); 

И, наконец:

@Stateless 
public class DataAccess { 

    @PersistenceContext 
    EntityManager em; 

    public void saveCountry(Country country) { 
     em.persist(country); 
    } 

    public void saveCitizen(Citizen citizen) { 
     em.persist(citizen); 
    } 

    public Citizen getCitizenByName(String name) { 
     Query query = em.createQuery("SELECT c FROM Citizen c WHERE c.citizenName = :name"); 
     query.setParameter("name", name); 
     return (Citizen) query.getSingleResult(); 
    } 

    public List<Country> getAllCountries() { 
     Query query = em.createQuery("SELECT c FROM Country c"); 
     return (List<Country>) query.getResultList(); 
    } 


} 
+0

Разве это не возможно для извлечения аниме я хочу от определенного пользователя с JOIN запросом? Или это возможно только через получение пользователя и получение списка, когда у меня есть объект от пользователя. – PieterJan

+0

Я не уверен, понимаю ли я ваш вопрос. Я попытался максимально упростить JPQL, и пусть поставщик JPA сделает все остальное. Вы хотели получить все аниме, связанные с пользователем, верно? Просто замените страну в моем примере своим пользователем и гражданином с аниме, что и должно делать. – mmalik