title: Do I have to set both sides for a bidirectional relationship?
body: <pre><code>@Entity
  public class A {
      @GeneratedValue
      @Id
      private long id;
  
      public long getId() {
          return id;
      }
  
      public void setId(final long id) {
          this.id = id;
      }
  
      @OneToMany(mappedBy = "a")
      List&lt;B&gt; bs;
  
      public List&lt;B&gt; getBs() {
          return bs;
      }
  
      public void setBs(final List&lt;B&gt; bs) {
          this.bs = bs;
      }
  }
  @Entity
  public class B {
      @GeneratedValue
      @Id
      private long id;
  
      public long getId() {
          return id;
      }
  
      public void setId(final long id) {
          this.id = id;
      }
  
      @ManyToOne
      @JoinTable
      A a;
  
      public A getA() {
          return a;
      }
  
      public void setA(final A a) {
          this.a = a;
      }
  }
  </code></pre>
  
  <p>To establish the relationship, I have to call</p>
  
  <pre><code>b.setA(a);
  a.getBs().add(b);
  </code></pre>
  
  <p>Why is both necessary, Why is it not sufficient to do only</p>
  
  <pre><code>b.setA(a);
  </code></pre>
  
  <p>or</p>
  
  <pre><code>a.getBs().add(b);
  </code></pre>
  
  <p>?</p>
  
  <p>The relationship is stored in a join table, and <code>b.setA(a)</code> will update that join table.</p>
  
  <p>But when I do a query afterwards, <code>a.getBs()</code> is empty. Why is that?</p>
  
  <p>Here is a Test case that illustrates the question. Note that the very last assert fails.</p>
  
  <pre><code>public class QuickTestAB2 {
  
      private static String dbUrlBase = "jdbc:derby:testData/db/test.db";
  
      private static String dbUrlCreate = dbUrlBase + ";create=true";
  
      private static String dbUrlDrop = dbUrlBase + ";drop=true";
  
      private EntityManagerFactory factory;
  
      private EntityManager em;
  
      public Map&lt;String, String&gt; createPersistenceMap(final String dbUrl) {
          final Map&lt;String, String&gt; persistenceMap = new HashMap&lt;&gt;();
          persistenceMap.put("javax.persistence.jdbc.url", dbUrl);
          return persistenceMap;
      }
  
      public void dropDatabase() throws Exception {
          if (em != null &amp;&amp; em.isOpen()) {
              em.close();
          }
          if (factory != null &amp;&amp; factory.isOpen()) {
              factory.close();
          }
          try (Connection conn = DriverManager.getConnection(dbUrlDrop)) {
  
          } catch (final SQLException e) {
              // always
  
          }
      }
  
      public void deleteDatabase() throws Exception {
          dropDatabase();
          final File file = new File("testData/db/test.db");
          if (file.exists()) {
              FileUtils.forceDelete(file);
          }
      }
  
      public void createNewDatabase() throws SQLException, IOException {
  
          FileUtils.forceMkdir(new File("testData/db"));
          try (Connection conn = DriverManager.getConnection(dbUrlCreate)) {
  
          }
      }
  
      @BeforeClass
      public static void setUpBeforeClass01() throws Exception {
          Tests.enableLog4J();
          JPATests.enableJPA();
  
      }
  
      @AfterClass
      public static void tearDownAfterClass01() throws Exception {
  
      }
  
      @Before
      public void setUp01() throws Exception {
  
          deleteDatabase();
          createNewDatabase();
          final Map&lt;String, String&gt; map = createPersistenceMap(dbUrlCreate);
          factory = Persistence.createEntityManagerFactory("pu", map);
  
      }
  
      @After
      public void tearDown01() throws Exception {
          if (em != null &amp;&amp; em.isOpen()) {
              em.close();
          }
          em = null;
          if (factory != null &amp;&amp; factory.isOpen()) {
              factory.close();
          }
          factory = null;
      }
  
      @Test
      public void test01() throws Exception {
          em = factory.createEntityManager();
          final A a = new A();
          final B b = new B();
          b.setA(a);
          try {
              em.getTransaction().begin();
              em.persist(a);
              em.persist(b);
              em.getTransaction().commit();
          } finally {
              em.close();
          }
          em = factory.createEntityManager();
          B b2;
          A a2;
          try {
              em.getTransaction().begin();
              Query q = em.createQuery("SELECT b FROM B b");
              b2 = (B) q.getSingleResult();
              q = em.createQuery("SELECT a FROM A a");
              a2 = (A) q.getSingleResult();
              em.getTransaction().commit();
          } finally {
              em.close();
          }
          assertThat(a2, is(not(nullValue())));
          assertThat(b2, is(not(nullValue())));
  
          assertThat(b2.getA(), is(not(nullValue())));
          assertThat(a2.getBs().isEmpty(), is(false));
  
      }
  
  }
  </code></pre>
  
  <p><strong>Motivation:</strong> It can be useful to change a bidirectional relationship by changing "only one side", when the number of <code>a.Bs</code> gets large. In this case, an <code>UPDATE SELECT</code> query on the owning side is much faster than to call <code>a.getBs().remove(b)</code>
  See also <a href="https://stackoverflow.com/questions/48692098/update-entity-relationship-via-update-set-query">here</a>.</p>