【问题标题】:Retrieveing list from a many-to-many relation with JPA/HQL从与 JPA/HQL 的多对多关系中检索列表
【发布时间】:2016-06-03 05:18:06
【问题描述】:

我有 3 个类,我正在尝试获取用户订阅的事件主机的所有事件的列表。我可能想得太复杂了,但我对 JPA/HQL 的经验很少。

用户类

@ManyToMany
    @JoinTable(name = "Subscriptions", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id") , inverseJoinColumns = @JoinColumn(name = "event_host_id", referencedColumnName = "id") )
    private List<EventHost> subscriptions;

EventHost 类

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "event_host_id", referencedColumnName = "id", updatable = true)
private List<Event> events;

我尝试使用此查询,但它告诉我未映射订阅,因为它不是 java 类。

String hql = "SELECT o FROM Event WHERE event_host_id IN (SELECT a FROM EventHost WHERE id IN(SELECT b FROM User WHERE = + " + userid + "))";

我知道像这样注入用户 ID 是不好的做法,我只是为了测试目的。

请问您是否需要更多内容,我真的很想了解如何为此编写查询。

【问题讨论】:

    标签: java mysql jpa hibernate-entitymanager


    【解决方案1】:

    这个问题确实应该是HQL with two join tables,但我会让你改变它。由于它的 HQL 或 JPA,它是独立于数据库的。

    无论如何,每当您看到OneToManyManyToMany 关系时,您就有了join table,因此您应该考虑加入。查看 sql create table 语句以了解发生了什么总是一个好主意。在这种情况下,您的 user_subscriptions 连接表是:

    create table user_subscriptions (user_id integer not null, subscriptions_id integer not null)
    

    你的event_host_events 连接表是这样的:

    create table event_host_events (event_host_id integer not null, events_id integer not null)
    

    那里没有什么新鲜事。当你试图让一些你无法直观理解的新事物发挥作用时,把它分解成你可以做的事情。例如,您可以执行两个查询,首先获取Users 订阅,然后获取这些订阅的Events

    Query query = session.createQuery("select u.subscriptions from User u where name = :name");  
    query.setParameter("name", name);
    List<EventHost> subscriptions = query.list();
    List<Event> events = new ArrayList<Event>();
    Query query2 = session.createQuery("select s.events from EventHost s where id = :id");  
    for (EventHost s: subscriptions ) {
        query2.setParameter("id", s.getId());
        events.addAll( query2.list());
    }
    

    不优雅,但它有效。然后,牢记join,弄清楚如何从他们两个中做出一个陈述。

    Query query = session.createQuery("select s.events from User u join u.subscriptions s where u.name = :name)");  
    query.setParameter("name", name);
    return query.list();
    

    默认情况下,加入将使用inner join,所以你没问题。 JPA 提供程序会自动为您加入三个Entity 表和两个Join Tables

    select 
        event4_.id as id1_2_
    from user user0_ 
        inner join user_subscriptions subscripti1_ on user0_.id=subscripti1_.user_id 
        inner join event_host eventhost2_ on subscripti1_.subscriptions_id=eventhost2_.id 
        inner join event_host_events events3_ on eventhost2_.id=events3_.event_host_id 
        inner join event event4_ on events3_.events_id=event4_.id 
    where user0_.name=?
    

    您是否很高兴不必编写该查询?

    【讨论】:

    • 哇,谢谢!这是一个惊人的解释:)!我会尽快对其进行测试,但我猜这会奏效,如果没有,它已经提供了足够多的信息让我弄清楚。是的,非常高兴!
    猜你喜欢
    • 2012-04-09
    • 2018-02-12
    • 2021-02-26
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    • 2016-09-01
    • 1970-01-01
    相关资源
    最近更新 更多