Skip to content
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

Support for loading multiple entities by id #321

Open
sebersole opened this issue May 6, 2021 · 3 comments · May be fixed by #659
Open

Support for loading multiple entities by id #321

sebersole opened this issue May 6, 2021 · 3 comments · May be fixed by #659
Labels
candidate-for-4 Good candidate for JPA 4

Comments

@sebersole
Copy link
Contributor

I propose the spec add the capability to load multiple entities by id at one time (multi-load).

Many use cases require loading multiple entities at once. Querying could definitely be an option.

EntityManager em = ...;
List<Product> products = em.createQuery( "select p from Product p where p.id in (:ids)", Product.class )
        .setParameter( "ids", Arrays.asList( 1, 2, 3, 4 )
        .getResultList();

However, that has a few drawbacks - the main one being potentially returning way too much data from the database when many ids are requested and a significant number of them are already managed in the EntityManager.

To really get this full capability with JPA today, a user would need to perform a complex series of calls. E.g.

EntityManager em = ...;
EntityManagerFactory emf = em.getFactory();

int[] ids = new int[] { 1, 2, 3, 4 }
List<Product> products = new ArrayList<>();

for ( Integer id : ids ) {
    // see if it already exists...
    //    NOTE : overly simplistic...
    Product existing = em.getReference( Product.class, id );
    
    if ( emf.getPersistenceUnitUtil().isLoaded( existing ) ) {
        products.add( existing );
    }
    else {
        // we could get fancy here and collect the ids to load from db and issue one query, 
        // but lets do the simple thing here for illustration purposes
        products.add( initializeProxy( product ) );
    }
}

One option for API in JPA would be overloads of the existing #find methods (assuming we don't want multiple #getReference loading):

interface EntityManager {
    ...
    // existing
    <T> T find(Class<T> entityType, Object id);
    <T> T find(Class<T> entityClass, Object id, LockModeType lockMode);
    <T> T find(Class<T> entityClass, Object id, LockModeType lockMode, Map<String, Object> properties);
    <T> T find(Class<T> entityClass, Object id, Map<String, Object> properties); 

    // additions
    <T> List<T> find(Class<T> entityType, Object... ids);
    <T> List<T> find(Class<T> entityClass, Map<String, Object> properties, Object... ids); 
    <T> List<T> find(Class<T> entityClass, LockModeType lockMode, Object... ids);
    <T> List<T> find(Class<T> entityClass, LockModeType lockMode, Map<String, Object> properties, Object... ids); 
}

Possibly accepting List of ids in addition to or instead of:

interface EntityManager {
    ...
    <T> List<T> find(Class<T> entityType, List<?> ids);
    <T> List<T> find(Class<T> entityClass, Map<String, Object> properties, List<?> ids); 
    <T> List<T> find(Class<T> entityClass, LockModeType lockMode, List<?> ids);
    <T> List<T> find(Class<T> entityClass, LockModeType lockMode, Map<String, Object> properties, List<?> ids); 
}
@gavinking
Copy link
Contributor

This capability almost made it into #383, but with the change of direction there, it's missed out.

Nevertheless, I think we should consider this feature for inclusion in JPA 3.2.

@gavinking gavinking added the candidate-for-4 Good candidate for JPA 4 label Aug 23, 2023
@gavinking
Copy link
Contributor

I now formally propose we add:

<E> List<E> findAll(Class<E> entityType, List<Object> ids, FindOption... options);

to EntityManager.

@gavinking
Copy link
Contributor

Note that the name is up for debate. Probably findMultiple() is better!

gavinking added a commit to gavinking/jpa-api that referenced this issue Sep 20, 2024
@gavinking gavinking linked a pull request Sep 20, 2024 that will close this issue
@gavinking gavinking linked a pull request Sep 20, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
candidate-for-4 Good candidate for JPA 4
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants