Talap Kurmanov
Talap Kurmanov

Reputation: 33

How to make multiple save methods in spring data JPA?

I had a slow performance of default save method in spring data jpa. So, i decided to make save method work asynchronously cause i did not need response in this specific method.

@Repository
public interface WorkplaceRepo extends JpaRepository<Workplace, Long> {
    @Async
    public <S extends Workplace> S save(S workplaceE);

It caused the problem that all save methods in whole project started to call this asynchronous method. The question is: how to use both save methods without losing one of them(default version and async version)

i thought to create custom insert method using native query, but the entity have so many columns and foreign keys, and i am not sure that it would work correctly.

Upvotes: 3

Views: 1735

Answers (3)

Talap Kurmanov
Talap Kurmanov

Reputation: 33

For those who faced same issue i would recommend to read this article. It gave good understanding of how spring data works inside, and solution of my problem. https://medium.com/@sridharmcakec/refactor-jpa-save-method-to-improve-application-performance-b7a77db2794c

My solution:

public interface CustomWorkplaceRepo {
    void saveAsync (Workplace workplace);
}

Then I implemented CustomWorkplaceRepo

public class CustomWorkplaceRepoImpl implements CustomWorkplaceRepo {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    @Async
    @Transactional
    public void saveAsync(Workplace workplace) {
        entityManager.persist(workplace);
    }
}

The last step was adding to extends new interface in my old Repo

public interface WorkplaceRepo extends JpaRepository<Workplace, Long>, CustomWorkplaceRepo {

That's it. Now, in service when I want to save Workplace Entity it is possible to call "saveAsync" method

Upvotes: 0

Evgeny K
Evgeny K

Reputation: 3157

I would suggest creating new repository WorkplaceRepoAsync with one save method something like this:

@Repository
public interface WorkplaceRepoAsync extends Repository<Workplace, Long> {
    @Async
    public <S extends Workplace> S save(S workplaceE);
}

UPDATE

Much better solution will be create WorkplaceService with @Async logic method

@Repository
public interface WorkplaceRepo extends JPARepository<Workplace, Long> {}
@Service
public class WorkplaceService {
    
    @Inject
    private WorkplaceRepo workspaceRepo;

    @Async
    public Workspace saveAsync(Workspace workspace) {
        workspaceRepo.save(workplace);
    }
}

Upvotes: 1

Panagiotis Bougioukos
Panagiotis Bougioukos

Reputation: 19108

You can try with the following code to have both methods available:

@Repository
public interface WorkplaceRepo extends JpaRepository<Workplace, Long> {
      @Async
      default <S extends Workplace> S saveAsync(S workplaceE) {
         return this.save(workplaceE);
      }
} 

This way the inherited not async method save(S entity) from JpaRepository would still be available to be called from your WorkplaceRepo.

Upvotes: 2

Related Questions