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

I want to do a countribution where methods with batch keywords are processed through the persistence context. #3360

Open
sami355-24 opened this issue Feb 9, 2024 · 4 comments
Labels
status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged

Comments

@sami355-24
Copy link

While looking for query optimization, I learned about the Batch keyword provided by Data JPA. And I also learned that the performance varies depending on the presence or absence of the Batch keyword. However, when adding the Batch keyword, I found that the "IN" keyword sends the query at once, but it processes it without going through the persistence context.

In response, I thought it would be good to modify the code so that methods with the Batch keyword are processed through the persistence context. If my idea feels valid, can I do a countribution on this?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Feb 9, 2024
@mp911de
Copy link
Member

mp911de commented Feb 12, 2024

Would you mind providing some pseudo-code that explains what you want to achieve? We currently have a difficult time understanding what you're up to.

@mp911de mp911de added the status: waiting-for-feedback We need additional information before we can continue label Feb 12, 2024
@sami355-24
Copy link
Author

sami355-24 commented Feb 16, 2024

I'm not familiar with English, so I used a translator to leave an issue. So the writing can be a little awkward.

First of all, I'll tell you about the code that made me think of contribution with an example.
If you use deleteAll provided by Data Jpa, delete the entity one at a time through the persistence context, so @PostRemove, which is called when the value is deleted in the persistence context, works fine. This means that the entity has been deleted from the persistence context.

@SpringBootTest
class MemberRepositoryTest {

    @Autowired
    private MemberRepository memberRepository;

    @BeforeEach
    public void setUp() {
        for (int i = 0; i < 10; i++) {
            memberRepository.save(Member.builder()
                    .clubName("test" + i)
                    .build());
        }
    }

    @Test
    @DisplayName("PostRemove is invoked when deleting using deleteAll.")
    public void deleteAllTest() {
        memberRepository.deleteAll();
    }
}

result is..
image

And if you delete it using the method with the Batch keyword provided by Data JPA, @PostRemove will not be called. This means that the entity has not been deleted from the persistence context.

@SpringBootTest
class MemberRepositoryTest {

    @Autowired
    private MemberRepository memberRepository;

    @BeforeEach
    public void setUp() {
        for (int i = 0; i < 10; i++) {
            memberRepository.save(Member.builder()
                    .clubName("test" + i)
                    .build());
        }
    }

    @Test
    @DisplayName("PostRemove is not invoked when deleting using DeleteAll.")
    public void deleteAllInBatchTest() {
        memberRepository.deleteAllInBatch();
    }

}

result is..
image

And the pseudocode of what I suggest is as follows. (I wrote the pseudocode based on the SimpleJpaRepository<T, ID>)

  1. deleteAllInBatch()
function deleteAllInBatch() {
    Create a query string using the result of the getDeleteAllQueryString() method
    Create a Query object from the EntityManager
    Apply query hints

    // Suggestion start
    if (Type parameter T exists in Persistence Context)
        Delete all type parameters T present in the entity manager.
    // Suggestion end

    Execute the query
}
  1. deleteAllInBatch(Iterable<T> entities)
function deleteAllInBatch(entities: Iterable<T>) {
    Check if the 'entities' parameter is not null
    if (Check if 'entities' has elements) {
        Construct the delete query string using entity name
        Apply query and bind parameters using QueryUtils

        // Suggestion start
        if (Type parameter T exists in Persistence Context)
            Delete parameters T present in the entity manager.
        // Suggestion end

        Execute the delete query
    }
}
  1. deleteAllByIdInBatch(Iterable<ID> ids)
function deleteAllByIdInBatch deleteByIds(Iterable<ID> ids) {
    Check if 'ids' parameter is not null
    if (Check if 'ids' has elements) {
        if (Check if the entity has a composite ID) {
            For entities with composite ID, fetch references and delete all in batch 
            // If the deleteAllInBatch code is modified as I suggested, there is no need to modify the code here.
        } else {
            Construct the delete query string
            Construct the delete query object
            Set parameter 'ids' based on the type of 'ids' (Collection or other)
            Apply query hints and execute the delete query

            // Suggestion start
            if (Type parameter T exists in Persistence Context)
                Delete parameters present in the entity manager.
            // Suggestion end

            Execute the delete query
        }
    }
}

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Feb 16, 2024
@sami355-24
Copy link
Author

sami355-24 commented Feb 20, 2024

There was a typo in pseudocode. Methods with parameters(deleteAllByIdInBatch(Iterable<ID> ids), deleteAllInBatch(Iterable<T> entities)) have been modified to check if they exist in the entity manager and, if so, only delete them.

@sami355-24
Copy link
Author

Hello, I'm inquiring about any updates on this issue, please review it, thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged
Projects
None yet
Development

No branches or pull requests

3 participants