Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6975363
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T17:21:30+00:00 2026-05-27T17:21:30+00:00

I have a ManytoMany relationship between A and B, where A is the owning

  • 0

I have a ManytoMany relationship between A and B, where A is the owning side.
I define the ManyToMany in class A:

@ManyToMany(....)
private Set<B> bs

But I don’t want to expose set in B, so no @ManyToMany attribute defined in B (e.g Set as).
It stems a problem when I want to select all B entity which an A instance is mapped to using JPA QL. I can not do:

"SELECT b FROM B b JOIN b.as A WHERE A.id = :id"

I could have set fetch = Fetch.EAGER in the @ManyToMany properties and use A.getBs() to get related B. But I prefer not to use Fetch.EAGER.
Any suggestion?
Thanks

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T17:21:30+00:00Added an answer on May 27, 2026 at 5:21 pm

    no @ManyToMany attribute defined in B (e.g Set as)

    (I had to correct myself, because it seems omitting Set<A> as from B altogether won’t raise an exception.)

    If you only want to hide the Set<A> as in B, then you can declare it as private and use a bi-directional mapping (using the mappedBy property on the non-owning side of the relation). In this case the following query runs successfully:

    EntityManager em = ...
    String sql = "SELECT b FROM B b JOIN b.as a WHERE a.id = :id";
    TypedQuery<B> tq = em.createQuery(sql, B.class);
    tq.setParameter("id", 100);
    for (B b : tq.getResultList())
      System.out.println(b);
    

    (The example snippets are all based on the tables, data and entities found in the lower sections of the answer.)

    It prints:

    B{id=333, data=b}
    B{id=999, data=bbb}
    

    This JPQL query is the mapping of the following native SQL query:

    SELECT b.id, b.data 
    FROM a, b, a_has_b 
    WHERE a.id = a_has_b.a_id 
    AND b.id = a_has_b.b_id 
    AND a_id = 100;
    

    You basically want a uni-directional relation (by omitting the mappedBy from B—down below—or droppping Set<A> as). This way, however, you won’t be able to execute a query like you’ve described. Just no way it’ll work.

    The persistence provider will bark at you if there is no Set<A> as in B (property could not be resolved—in case of Hibernate). If you only omit the mappedBy from the non-owning side, then the persistence provider won’t know where is the other side of that relation. Either you use the mappedBy or create an inverse @JoinTable annotation in B too (mappedBy is there so that you don’t have to the latter).

    If you only have a uni-directional mapping from A towards B you can only fetch an A entity by its id and find all B entities that are associated with it, like this (just what you’ve described):

    TypedQuery<A> tq = em.createQuery("SELECT a FROM A a WHERE id = :id", A.class);
    tq.setParameter("id", 100);
    for (A a : tq.getResultList())
      for (B b : a.bs)
        System.out.println(b);
    

    This works for me without specifying fetch = Fetch.EAGER and prints the same stuff as before.

    Beware that if Fetch.LAZY is in effect you’ll receive errors if you try accessing lazily loaded entities after closing an EntityManager or (Hibernate) Session. You can’t do anything about this: this is the way it’s supposed to work.

    EntityManager em = ...
    // fetch your B instances
    List<B> bs = ...
    em.close();
    for (B b : bs)
      for (A a : b.as)
        // *BOOM*
        System.out.println(a);
    

    You can do two things to prevent BOOM from happening.

    1. Close your EntityManager or Session after you’re done with your A objects and don’t use them anymore. If you call b.as before em gets closed Hibernate (or any other persistence provider) will load A objects lazily from the database.
    2. On your B entity’s @ManyToMany annotation change fetch to FetchType.EAGER. This way, when you fetch B objects from the database their Set<A> as property will be loaded by Hiberate too (further control can be practiced with different CascadeType settings—I think).

    I propose that you use a bi-directional mapping instead (don’t omit mappedBy) or make B the owning side (but the former would be much useful).

    Tables

    test.a

    +-------+-------------+------+-----+---------+
    | Field | Type        | Null | Key | Default |
    +-------+-------------+------+-----+---------+
    | id    | int(11)     | NO   | PRI | 0       |
    | data  | varchar(45) | YES  |     | NULL    |
    +-------+-------------+------+-----+---------+
    

    test.b

    +-------+-------------+------+-----+---------+
    | Field | Type        | Null | Key | Default |
    +-------+-------------+------+-----+---------+
    | id    | int(11)     | NO   | PRI | 0       |
    | data  | varchar(45) | YES  |     | NULL    |
    +-------+-------------+------+-----+---------+
    

    test.a_has_b

    +-------+---------+------+-----+---------+-------+
    | Field | Type    | Null | Key | Default | Extra |
    +-------+---------+------+-----+---------+-------+
    | a_id  | int(11) | NO   | PRI | 0       |       |
    | b_id  | int(11) | NO   | PRI | 0       |       |
    +-------+---------+------+-----+---------+-------+
    

    Data

    test.a

    +-----+------+
    | id  | data |
    +-----+------+
    | 100 | a    |
    | 200 | aa   |
    | 300 | aaa  |
    +-----+------+
    

    test.b

    +-----+------+
    | id  | data |
    +-----+------+
    | 333 | b    |
    | 666 | bb   |
    | 999 | bbb  |
    +-----+------+
    

    test.a_has_b

    +------+------+
    | a_id | b_id |
    +------+------+
    |  100 |  333 |
    |  300 |  333 |
    |  100 |  999 |
    +------+------+
    

    Entities

    A

    @Entity
    @Table(schema = "test", name = "a")
    public final class A {
    
      @Id
      public int id;
    
      @Basic
      public String data;
    
      @ManyToMany(targetEntity = B.class,
                  cascade = CascadeType.ALL,
                  fetch = FetchType.LAZY)
      @JoinTable(schema = "test",
                 name = "a_has_b",
                 joinColumns = @JoinColumn(table = "a",
                                           name = "a_id",
                                           referencedColumnName = "id"),
                 inverseJoinColumns = @JoinColumn(table = "b",
                                                  name = "b_id",
                                                  referencedColumnName = "id"))
      public Set<B> bs = Sets.newLinkedHashSet();
    
      @Override
      public String toString() {
        return "A{id=" + id + ", data=" + data + "}";
      }
    }
    

    B

    @Entity
    @Table(schema = "test", name = "b")
    public final class B {
    
      @Id
      public int id;
    
      @Basic
      public String data;
    
      // omitting mappedBy results in a uni-directional relationship
      @ManyToMany(targetEntity = A.class,
                  cascade = CascadeType.ALL,
                  fetch = FetchType.LAZY,
                  mappedBy = "bs")
      public Set<A> as = Sets.newLinkedHashSet();
    
      @Override
      public String toString() {
        return "B{id=" + id + ", data=" + data + "}";
      }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a ManyToMany relationship between two classes, for instance class Customer and class
I have a @ManyToMany relationship between class A and class B : class A
I want to persist my entity with ManyToMany relation. But i have some problem
I have ManyToMany relationship between Author and Book . table : AUTHOR id |
I have a many-to-many relationship between 2 tables that I define with a join
I have an entity class set up in Java, with a many-to-many relationship to
I have a pretty simple JPA @ManyToMany relationship set up in my application. A
Simple JPA/JPQL question. I have an entity with a ManyToMany relationship: @Entity public class
I have a ManyToMany relationship between person that I'm trying to describe with Hibernate
I have a ManyToMany field with a relationship model. I want a formset, filtered

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.