Hibernate checks the state of entities when committing transactions. This is useless and performance-critical when fetching large amounts of data to send to the client.
I found a solution with
 entityManager.setFlushMode(FlushModeType.COMMIT);
I put back auto after the query.
Are there any normal more compact solutions.
Now I'm thinking of doing something similar to aspectJ so I don't clutter up the code and I can annotate both the service and the repository. What do you think about this and how do you solve such a problem?
Example:
@Override
public Collection<ZoomCallInfoDTO> findZoomCalls(Collection<ContactId> invitedUsers, String name, Date startTime, Date endTime, int offset, int limit, boolean asc, callId callId)
{
    // Why we did it?
    // Due to bad logic of finding calls in time interval (ZoomCallRepository#findAllByProfileAndcallWithinRange)
    // which loaded all calls for user to compute periodical calls there are TOO many entities in hibernate.
    // So during converting calls to DTOs we also have N x M queries (N - number of call to return, M - number of queries for each call conversion).
    // Each query makes hibernate checks all loaded entities for autoFlush policy. And we have bad performance ((
    // Possible decisions:
    // 1. Switch off autoFlush policy for GET methods:
    //    1.1 - Use readOnly transaction (not good for us now because stating top transaction logic is not managed)
    //    1.2 - Set flushMode manually (not good as persistence decision but the cheapest now) - CURRENTLY USED
    // 2. Decrease number of loaded to hibernate entities - it need to redesign logic of computing periodical calls
    // 3. Merge of 1 and 2 decisions - SHOULD BE IMPLEMENTED IN FUTURE
    entityManager.setFlushMode(FlushModeType.COMMIT);
    if (invitedUsers != null && !invitedUsers.isEmpty())
    {
        throw new RuntimeException("Search by invited users is not supported.");
    }
    UserProfile profile = callUtil.getCurrentUserProfile();
    List<ZoomCallInfoDTO> callDTOs = new ArrayList<>();
    Map<callId, callCacheItem> callCache = new HashMap<>();
    for (ZoomCall call : ZoomCallRepository.findAllByProfileAndcallWithinRange(profile.getId(), name, startTime, endTime, offset, limit, asc, callId))
    {
        callDTOs.add(create(call, profile.getId(), callCache));
    }
    entityManager.setFlushMode(FlushModeType.AUTO);
    return callDTOs;
}
I noticed that after such operations there is an "autoflush" there are too many of them
 
     
    