Skip to content

Defer EntityManager flushing and clearing in JpaPagingItemReader [BATCH-1110] #2465

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Mar 1, 2009 · 5 comments

Comments

@spring-projects-issues
Copy link
Collaborator

Hamdi Makni opened BATCH-1110 and commented

We can add clearAfterFlush with default value = true in the JpaPagingItemReader and just make a simple test before clearing the entity manager:
if (clearAfterFlush)
entityManager.clear();
a StepListener (using StepListenerSupport) can be added to the step to clear the EntityManager after writing.

I'll write this listener and post it to this issue later


Affects: 2.0.0.M4

Reference URL: http://forum.springframework.org/showthread.php?t=68138

Issue Links:

  • BATCH-1166 Modify JpaPagingItemReader/Writer to support an extended persistence context
@spring-projects-issues
Copy link
Collaborator Author

Hamdi Makni commented

Finally, i used a ChunkListener:

import java.util.HashMap;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import org.springframework.batch.core.listener.ChunkListenerSupport;
import org.springframework.dao.DataAccessResourceFailureException;

/**

  • @author Hamdi Makni

*/
public class ClearEntityManagerAfterWriteListener extends ChunkListenerSupport {

protected EntityManagerFactory entityManagerFactory;

@Override
public void afterChunk() {
EntityManager entityManager = entityManagerFactory
	.createEntityManager(new HashMap<String, Object>());
if (entityManager == null) {
    throw new DataAccessResourceFailureException(
	    "Unable to obtain an EntityManager");
}

entityManager.clear();

super.afterChunk();
}

public EntityManagerFactory getEntityManagerFactory() {
    return entityManagerFactory;
}

public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
    this.entityManagerFactory = entityManagerFactory;
}

}

@spring-projects-issues
Copy link
Collaborator Author

Dave Syer commented

Isn't this problem a little more subtle? Unless the page size is aligned with the commit interval, then flush and clear should either always happen, or only in a transaction synchronization (which might be already provided by the transaction manager?).

@spring-projects-issues
Copy link
Collaborator Author

Thomas Risberg commented

It is much more subtle. We need to switch the paging reader to use a shared transactional em and make sure the transaction commits don't clear the session. This requires an extended persistence context that we must share between the reader, processor and writer. We would also have to consider any classes that use @PersistenceContext annotation.

To accomplish this requires a lot more work. Maybe for a 2.1 release.

-Thomas

@spring-projects-issues
Copy link
Collaborator Author

Thomas Risberg commented

Thinking about it some more - there are two separate issues.

  1. provide lazy loading of items read

  2. provide same persistence context for reader, processor and writer

I think what Hamdi was asking for was #1 while my earlier comments addressed #2. I'll create another issue for the extended persistence context (#2) and will solve #1 for now. I can simply move the clear to before the page is read rather than after. This should work fine in all cases.

-Thomas

@spring-projects-issues
Copy link
Collaborator Author

Thomas Risberg commented

moved flush/clear to before page read to allow for lazy-loading of properties of page result items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant