Custom delete method in JpaRepository

Viewed 7521

I'd like to know if there's a way of overriding the delete method for some of my JpaRepository's without having to override the rest of the methods.

Currently I have something like

public interface UserRepo extends JpaRepository<User, Long>
{
    findUserById(long id);

    findUserByEmail(String email);

    // etc...
}

And I'd like to override the delete(T Entity) method in CrudRepository. To do so I've tried implementing the UserRepo but then I have to implement all the findByX and haven't really find anything around on how to properly do that.

Is there any annotation to add to a function in the Entity class so it runs when you call UserRepo.delete(myUser)?

Thanks in advance!

7 Answers

Not sure I understand you clear enough, but lets try:

... I have to implement all the findByX ...

You don't, spring will generate JPQL snippet if you name methods in your interface with suitable convection please take a look at this and this articles

... Is there any annotation to add to a function in the Entity class so it runs when you call UserRepo.delete(myUser)? ...

You can use @PreRemove / @PostRemove annotation on method in your entity class:

@PreRemove / @PostRemove
public void someMethod() { ... }

In addition to Raheela Aslam post:

Spring-data documentation has an example of how you can override standard repository methods, for example:

interface CustomizedSave<T> {
  <S extends T> S save(S entity);
}

class CustomizedSaveImpl<T> implements CustomizedSave<T> {

  public <S extends T> S save(S entity) {
    // Your custom implementation
  }
}

interface UserRepository extends CrudRepository<User, Long>, CustomizedSave<User> {
}

You can read about it there: https://docs.spring.io/spring-data/jpa/docs/2.1.2.RELEASE/reference/html/#repositories.custom-implementations

UPD: Read it carefully, because there are some important things, e.g The most important part of the class name that corresponds to the fragment interface is the Impl postfix.

Also the documentation says: Custom implementations have a higher priority than the base implementation and repository aspects.

If you want to keep Spring's behavior for deletion, but want to have some logic to be executed either before or after, you may utilize java8's interface default methods, and try the following :

public interface UserRepo extends JpaRepository<User, Long> {

    default void customDelete(User user) {
       // before logic
       // ..
       delete(user); // actual call to deletion
       // after logic
       // ..
     }

}

In your case code will be like as below:

public interface UserRepo extends JpaRepository<User, Long>
{
    findUserById(long id);

    findUserByEmail(String email);

    // etc...
}

public interface UserRepositoryCustom {

    void deleteByEmail(String email);
}

public interface UserRepositoryImpl implements UserRepositoryCustom {

    public void deleteByEmail(String email) {
        //provide your custom implimentation
    }
}

There are several ways to do this depending on what you're trying to do:

I prefer to use method naming if possible, the method name gets long, but you know exactly what it does by looking at it.

Hi you can write your own Interface write implementation with EntityManager and extend in you interface here is the sample :

Actually one more way is writing by soemthing like :

 User findByUsername(String username) // it will find the user by specific username 

spring data will create you an implementation of this method The same way you can create your own delete method

Here is useful links:

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations

In this link you can go to part 2.3 QueryMethods:

You can also define @NameQuery in your entity class:

@Entity
@Table(name = "employee", schema="spring_data_jpa_example")
@NamedQuery(name = "Employee.yourMethodQueryName",
        query = "yourQuery"
)
public class Employee {}

@Repository
public interface EmployeeRepository extends JpaRepository<Employee,Long> {

    List<Employee> yourMethodQueryName(Your list of params);
}

Here is link with sample:

I think this is helpful for you

public interface UserRepo extends JpaRepository<User, Long> {
    @Modifying
    @Query("delete from User u where u.email = ?1")
    void deleteByEmail(String email);

}
Related