简体   繁体   English

使用Spring Data 4 JPA的自定义保存方法

[英]Custom save method with Spring Data 4 JPA

I know Spring Data uses SimpleJpaRepository as the implementation of JpaRepository . 我知道春天的数据使用SimpleJpaRepository作为实施JpaRepository I am looking forward to override its save method for certain Repositories. 我期待为某些存储库覆盖其save方法。 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. 我已经尝试在MyEntityJpaImpl类中扩展SimpleJpaRepository ,但是它没有提供适合自动装配的默认构造函数。

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: 和最相关的stacktrace部分:

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 您可以通过在扩展JpaRepository的接口内编写自己的方法来提供自定义实现

Two ways to do this : 有两种方法可以做到这一点:

1 . 1。 You can use @Query annotation and write query inside it. 您可以使用@Query批注并在其中编写查询。

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

2 . 2。 You can use NamedQuery and give reference to you method. 您可以使用NamedQuery并引用您的方法。

@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. spring-data的文档中包含一些示例,可以完全解决您的问题。

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

Example 30. Fragments overriding save(…) 例子30.覆盖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 例子31.定制的仓库接口

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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