title: Eclipselink - detached entities memory leak
body: <h1>Setup</h1>
  <p>We are currently using wildfly with eclipselink as JPA implementation in JakartaEE application. Application itself is RESTful web server with REST, Service and DAO layers. DAO is the only layer that is using EntityManager. We are always detaching entities for various reasons.</p>
  <ul>
  <li>To prevent eclipselink from automatic state checking and flushing changes to database</li>
  <li>To prevent eclipselink from reusing same object on multiple reads
  ...</li>
  </ul>
  <p>However by using this approach we have noticed spike in memory usage that in some cases lead to <code>OutOfMemory</code> errors.</p>
  <h1>Diagnostics</h1>
  <p>Using VisualVM we have pinpointed problem to be having a great number of instances of entities in memory.</p>
  <h2>Test code</h2>
  <p>This is sample of code we are experiencing problems with (migration of some historic data)</p>
  <pre><code>LinkedList&lt;SomeEntity&gt; entities; //Here is loaded set of entities to process
  while(!entities.isEmpty()) {
      SomeEntity entity = entities.removeFirst(); //We are iterating in quee fashion to allow GC to remove already processed items from memory
      if (entity.getItems().isEmpty()) {
          //this call is transactional
          entityService.delete(entity.getId());
       } else if (entity.getItems().stream().anyMatch(item -&gt; item.getQuantity() &gt; 0.0)){
          //DO SOME CHANGES ON ENTITY
          //this call is transactional
          entityService.update(operation);
       }
       entity = null;
  }
  entities = null;
  </code></pre>
  <h2>Observations</h2>
  <ul>
  <li>While profiling memory usage we can see ever increasing count of entity classes in memory. It is not the same entity that is being worked with in test code, but it is entity, that is referenced at most time by other objects. Sometimes part of them are cleared but overall number increases after some time</li>
  <li>Number of instances greatly outnumbers records in database</li>
  <li>This means that every time object is referenced in relation, new instance is created (this is OK)</li>
  <li>When we have created heap dump and looked from where the objects are referenced only eclipselink internal structures shows like
  <code>relationshipSourceObject in org.eclipse.persistence.internal.indirection.UnitOfWorkQueryValueHolder#90312</code>
  <code>owner in org.eclipse.persistence.internal.descriptors.changetracking.AttributeChangeListener#26713</code>, ...)</li>
  </ul>
  <h1>What we have tried</h1>
  <p>None of this helped:</p>
  <ul>
  <li>Setting eclipselink.cache.type.default to WEAK, SOFT or even NONE</li>
  <li>Manually calling EntityManager.clear at end of the while</li>
  </ul>
  <p>In my understanding WEAK should be enough to prevent eclipselink from storing references for too long and prevent GC. But it is stored somewhere anyway and since that references are accessible from GC roots they are newer cleared. Can anyone explain this behavior or point me at direction where to look?</p>
  <h1>EDITS</h1>
  <p>Addressing comment and Chris answer. More information about how we use EM and transactions.</p>
  <p>We are detaching using EntityManager.detach method and references (<code>@OneToMany</code>, <code>@ManyToMany</code>, etc) have Cascade.DETACH applied. Loading necessary lazy loaded references is done prior to detach.</p>
  <p>I agree about the part about re-fetching entities. I would not mind having multiple instances of the same entity in memory for some time. My problem is why it is not garbage collected.</p>
  <p>List of entities in sample code is loaded in one transaction on subsequent database UPDATE or DELETE (this also fetches some bits into memory creating more instances) is another transaction per entity. I would probably expect most of the heap used during the initial call and then slowly clearing or remaining roughly same.</p>
  <p>About using EntityManager</p>
  <p>We are using wildfly as JakartaEE container. By default it is shipped with hibernate as JPA provider but we have added eclipselink as module and configured provider in persistence.xml</p>
  <p>According to <a href="https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.1/html/development_guide/java_persistence_api_jpa#container_managed_entitymanager" rel="nofollow noreferrer">documentation</a> container managed EntityManager creates instances as needed.</p>