4

This questions is the same as this one with a twist.

I have an interface such as :

@Repository
public interface InvoiceRepository extends JpaRepository<Invoice, String>{

  // some other methods here 

 default Invoice save(Invoice invoice) {

        //I do sth here

        return JpaRepository.super.save(invoice); // wonT work
    }

}

How can i call the save method of the implemented JPA interface?


Update: Indeed i noticed, save is not a default in the extended JPARepository interface

In this case, what would be the best way of achieving this ?

  • override save method

  • call the parent save method in the overridden method

Orkun
  • 6,998
  • 8
  • 56
  • 103

2 Answers2

3

The default method you defined is helpless as Spring will implement out of the box a method with the same erasure (see CrudRepository.save()).

Here you don't invoke a default method of an interface :

JpaRepository.super.save(invoice); 

you invoke the abstract save() method of CrudRepository.
But it cannot compile as it is abstract.
It could work as in the quoted question if the JpaRepositorysuper class defined a default save() method but that is not the case.

In this case, what would be the best way of achieving this ?

You could create a default method with a distinct name and from it call save() that at runtime will invoke the runtime InvoiceRepository instance :

default Invoice saveInvoice(Invoice invoice) {
    // I do sth here
    ...
    return save(invoice); 
}
davidxxx
  • 125,838
  • 23
  • 214
  • 215
2

In your case, the method save() is not default. From the code, its defined as :

<S extends T> S save(S var1); // abstract, public

Note - Worth mentioning, the code belongs to the artifact org.springframework.data:spring-data-jpa:2.0.9.RELEASE.

Or if I could say, your inference is incorrect, "default is not implied by default."

Naman
  • 27,789
  • 26
  • 218
  • 353