简体   繁体   中英

Custom save method with Spring Data 4 JPA

I know Spring Data uses SimpleJpaRepository as the implementation of JpaRepository . I am looking forward to override its save method for certain Repositories. Is there any way that doesn't imply replacing the default implementation for all my repositories?

I've already tried to extend SimpleJpaRepository in my MyEntityJpaImpl class but it does not provide a default constructor suitable for autowiring.

EDIT:

Here is the class I'm trying to autowire

public class MyEntityJpaImpl<ClientesCentro, ClientesCentroPK extends Serializable> extends SimpleJpaRepository<ClientesCentro, ClientesCentroPK> implements ExtendedRepository<ClientesCentro, ClientesCentroPK>{

    private JpaEntityInformation<ClientesCentro, ClientesCentroPK> entityInformation;
    @PersistenceContext
    private EntityManager em;
    private Class<ClientesCentro> clazz;

    public MyEntityJpaImpl(Class<ClientesCentro> domainClass, EntityManager em) {       

        this((JpaEntityInformation<ClientesCentro, ClientesCentroPK>) JpaEntityInformationSupport.getMetadata(domainClass, em), em);
        this.clazz = domainClass;
    }

    public MyEntityJpaImpl(JpaEntityInformation<ClientesCentro, ClientesCentroPK> jpaEntityInformation, EntityManager entityManager) {
        super((JpaEntityInformation<ClientesCentro, ClientesCentroPK>) jpaEntityInformation, entityManager);
        this.entityInformation =  jpaEntityInformation;
        this.clazz = this.entityInformation.getJavaType();
        this.em = entityManager;
    }

    public void refresh() {

    }

    @Transactional
    @Override
    public <S extends ClientesCentro> S save(S entity) {
            System.out.println("Hello world!");

            if (entityInformation.isNew((ClientesCentro) entity)) {
                em.persist(entity);
                return entity;
            } else {
                return em.merge(entity);
            }
    }   
}

And the most relevant stacktrace part:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.xxxyyy.erp.dal.repository.domain.MyEntityJpaImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.xxxyyy.erp.dal.repository.domain.MyEntityJpaImpl.<init>()
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:85)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1094)
    ... 55 common frames omitted
Caused by: java.lang.NoSuchMethodException: com.xxxyyy.erp.dal.repository.domain.MyEntityJpaImpl.<init>()
    at java.lang.Class.getConstructor0(Unknown Source)
    at java.lang.Class.getDeclaredConstructor(Unknown Source)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80)
    ... 56 common frames omitted

You Can Provide Custom Implementation by writing your own method inside interface which extends JpaRepository

Two ways to do this :

1 . You can use @Query annotation and write query inside it.

@Query("-----Query here------")
public List<Employee> getEmp();

2 . You can use NamedQuery and give reference to you method.

@Query(name="HQL_GET_ALL_EMPLOYEE_BY_ID")
public List<Employee> getEmpByIdUsingNamedQuery(@Param("empId") Long   
empId); 

The documentation for spring-data contains examples solving exactly your problem.

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.single-repository-behavior

Example 30. Fragments overriding save(…)

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
  }
}

The following example shows a repository that uses the preceding repository fragment:

Example 31. Customized repository interfaces

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

interface PersonRepository extends CrudRepository<Person, Long>, CustomizedSave<Person> {
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM