首页 > 解决方案 > Spring Java Config DI 定义和 JpaRepository 的(“具体接口”)

问题描述

我有下面的代码。

请注意,我有一个接口 MySuperCoolEntityRepositoryContract。

而且我有一个“具体接口”MySuperCoolEntityJpaRepository,它实现了我上面的 MySuperCoolEntityRepositoryContract 接口和 JpaRepository。

所有这些都适用于@ComponentScan。

我正在将我的代码更改为“java config”,也就是我可以编写我的 DI 定义的集中位置。(在某些圈子中也称为 CompositionRoot)。

问题是当我尝试为接口“编码”具体内容时。(跳到这个问题的后面。

package com.me.domain.jpaentities;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Transient;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;

@Entity(name = "MySuperCoolEntityTableName")
public class MySuperCoolEntity implements Serializable {

    @Id
    @Column(name = "CoolSurrogateKeyColumn")
    private String coolSurrogateKey;

    @Column(name = "CoolMagicValueColumn")
    private String coolMagicValue;


    public String getCoolSurrogateKey() {
        return this.coolSurrogateKey;
    }

    public void setCoolSurrogateKey(String coolSurrogateKey) {
        this.coolSurrogateKey = coolSurrogateKey;
    }

    public String getCoolMagicValue() {
        return this.coolMagicValue;
    }

    public void setCoolMagicValue(String coolMagicValue) {
        this.coolMagicValue = coolMagicValue;
    }

}

================

package com.me.dal.repositories.interfaces;

import com.me.domain.jpaentities.MySuperCoolEntity;
import java.util.Collection;

public interface MySuperCoolEntityRepositoryContract {

    Collection<MySuperCoolEntity> findByCoolMagicValue(String coolMagicValue);

}

==========================

package com.me.dal.repositories;

import com.me.dal.repositories.interfaces.MySuperCoolEntityRepositoryContract;
import com.me.domain.jpaentities.MySuperCoolEntity;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Collection;

@Repository
public interface MySuperCoolEntityJpaRepository extends MySuperCoolEntityRepositoryContract, JpaRepository<MySuperCoolEntity,String> {

    Collection<MySuperCoolEntity> findByCoolMagicValue(String coolMagicValue);

}

现在这个问题。

package com.me.myapplication.configuration;

import com.me.dal.repositories.MySuperCoolEntityJpaRepository;
import com.me.dal.repositories.interfaces.MySuperCoolEntityRepositoryContract;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyCompositionRoot {


    @Bean
    public MySuperCoolEntityRepositoryContract getAMySuperCoolEntityRepositoryContract()
    {
        return new MySuperCoolEntityJpaRepository();  /* << issue is here, this is an abstract class, aka, an interface with some methods defined */
    }

}

使用超酷的 JpaRepository “具体接口”又名“真正的抽象类,但称为接口”又名“接口默认方法”(参见https://dzone.com/articles/interface-default-methods-java)...... ……

确切的错误是:

MySuperCoolEntityJpaRepository is abstract; cannot be instantiated

我明白这个错误。MySuperCoolEntityJpaRepository 是抽象的。我明白了。

但是有了这个超酷的“只需扩展 JpaRepository 并获得各种默认功能”......

如何使用 Spring DI 注册一个具体的 JpaRepository(特别是使用“编码”java config?

…………

我试着把它变成一个“类”。

public class MySuperCoolEntityJpaRepository extends MySuperCoolEntityRepositoryContract, JpaRepository<MySuperCoolEntity,String>

但这要我定义所有内置方法,例如“findAll”等。

标签: spring-bootjpadependency-injectionspring-data-jpajpa-2.0

解决方案


Spring Boot 神奇地为您的接口中定义的方法提供了实现。扫描包下的@EnableJpaRepositories所有包以查找扩展JpaRepository的接口,并为其创建一个 Spring bean,该 bean 由SimpleJpaRepository的实现支持(spring data 通过此类提供 CRUD 存储库的默认实现)。

您的接口MySuperCoolEntityJpaRepository 扩展了接口MySuperCoolEntityRepositoryContract,但您只扩展了JpaRepository接口上的MySuperCoolEntityJpaRepository,这意味着 spring 只会为接口中的方法提供默认实现MySuperCoolEntityJpaRepository。所以试试吧:

public interface MySuperCoolEntityRepositoryContract extends JpaRepository<MySuperCoolEntity,String>{

    Collection<MySuperCoolEntity> findByCoolMagicValue(String coolMagicValue);

}

然后在您的存储库中扩展它,例如:

@Repository
public interface MySuperCoolEntityJpaRepository extends MySuperCoolEntityRepositoryContract {

    Collection<MySuperCoolEntity> findByCoolMagicValue(String coolMagicValue);

}

相关文章:java spring 中的注解@Repository 是如何工作的?


推荐阅读