关于 JPA 存储库和自动装配的 Java spring 问题

Posted

技术标签:

【中文标题】关于 JPA 存储库和自动装配的 Java spring 问题【英文标题】:Java spring problem concerning JPA repositories and autowire 【发布时间】:2020-11-25 22:15:04 【问题描述】:

我是一个老前辈,但对 spring 和朋友们来说还很陌生(也许我已经老了,生锈了,不要对我太苛刻)。我有一个非常非常类似于Unable to Field identify bean named 'entityManagerFactory' as using Auto-wiring annotation to Repository 中的问题,它目前击败了我......我无法找到为什么 springboot 应用程序的答案(这是我做的一件愚蠢的小事我的业余时间)似乎无法按应有的方式自动连接 jpa 存储库。我已经(据我所知)遵循了上面链接问题中的说明(并删除了任何已知的直接休眠依赖项。我也在这个公共问题中附上了我的 pom 文件。

<?xml version="1.0" encoding="UTF-8"?>

<modelVersion>4.0.0</modelVersion>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.2.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<groupId>se.pointsofinterest</groupId>
<artifactId>poi-restlayer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>restlayer</name>
<description>This module contains the rest layer for the application</description>

<properties>
    <java.version>11</java.version>
</properties>

<dependencies>

    <!--dependency>
        <groupId>se.pointsofinterest</groupId>
        <artifactId>dblayer</artifactId>
        <version>1.0.0</version>
    </dependency-->

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <version>2.3.1.RELEASE</version>
    </dependency>

    <!--dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-jpa</artifactId>
    </dependency-->

    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
        <version>1.4.200</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
            <!-- Possibly suspect depedencies below! -->
    <dependency>
        <groupId>org.springframework.restdocs</groupId>
        <artifactId>spring-restdocs-mockmvc</artifactId>
        <version>2.0.4.RELEASE</version>
        <scope>test</scope>
    </dependency>
            <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <scope>test</scope>
        <version>4.13</version>
    </dependency>
</dependencies>

<repositories>
    <!-- Main maven repository -->
    <repository>
        <id>central</id>
        <url>https://repo.maven.apache.org/maven2</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
    <!-- Repository where to store our local artifacts (an azure artifacts)! -->
    <repository>
        <id>joakimhansson</id>
        <url>https://pkgs.dev.azure.com/joakimhansson/_packaging/joakimhansson/maven/v1</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
</repositories>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

据我所知,我在这个 pom 中不依赖休眠。

我有一个数据库层,其中包含;

域(所有实体) 存储库(所有相关的存储库引用) 包含服务层的服务(为数据处理定义了更高的业务逻辑)。

尽我所能,这与上面提到的问题非常相似。

我得到的错误是;

***************************
APPLICATION FAILED TO START
***************************

Description:

Field mapLocationRepository in se.poi.restlayer.dblayer.services.MapLocationService required a bean named 'entityManagerFactory' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)

即..即自动连线功能不起作用。 我的应用程序配置;

package se.poi.restlayer;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import se.poi.dblayer.domain.*;
import se.poi.dblayer.repositories.AddressRepository;
import se.poi.dblayer.repositories.LinksRepository;
import se.poi.dblayer.repositories.MapLocationRepository;
import se.poi.dblayer.repositories.TagDefinitionsRepository;

/**
 *  * @author Joakim Hansson, 2020
 *
 */
@Slf4j
@SpringBootApplication(scanBasePackages = "se.poi.dblayer.repositories", "se.poi.dblayer.services")
/*@Import(value=ConfigurationDbLayer.class)
@ComponentScan(basePackages=
        "se.poi.dblayer",
        "se.poi.dblayer.domain",
        "se.poi.dblayer.repositories",
        "se.poi.dblayer.services")
*/
@EntityScan(basePackageClasses = 
        Address.class,
        Links.class,
        MapLocation.class,
        MapLocationTagDefinitionsRelation.class,
        TagDefinitions.class
)

@EnableJpaRepositories(basePackageClasses = 
        AddressRepository.class,
        LinksRepository.class,
        MapLocationRepository.class,
        TagDefinitionsRepository.class)
@ComponentScan(basePackages=
        "se.poi.restlayer.dblayer",
        "se.poi.restlayer.dblayer.domain",
        "se.poi.restlayer.dblayer.repositories",
        "se.poi.restlayer.dblayer.services")

public class Application 

    public static void main (String[] args) 
        log.info("Starting the main backend for the end customer for us.");
        log.info("------------------------------------------------------");
        //new BeanConfigurator();
        //AutowireCapableBeanFactory f = context.getContext().getAutowireCapableBeanFactory();
        //f.autowireBean(new AddressRepository());
        SpringApplication.run(Application.class, args);
    



存储库;

package se.poi.restlayer.dblayer.repositories;

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

import se.poi.dblayer.domain.Address;

@Repository
//@Component
public interface AddressRepository extends JpaRepository<Address, Long>


服务;

package se.poi.restlayer.dblayer.services;

import java.util.List;
import java.util.Optional;

import javax.annotation.PostConstruct;
import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

import lombok.extern.slf4j.Slf4j;
import se.poi.dblayer.domain.Address;
import se.poi.dblayer.domain.Links;
import se.poi.dblayer.domain.MapLocation;
import se.poi.dblayer.domain.TagDefinitions;
import se.poi.dblayer.repositories.AddressRepository;
import se.poi.dblayer.repositories.LinksRepository;
import se.poi.dblayer.repositories.MapLocationRepository;
import se.poi.dblayer.repositories.TagDefinitionsRepository;
//import org.springframework.web.context.annotation.ApplicationScope;
/**
 * Demo backend that accepts up to 100 fishing spots. Data is shared with all
 * users.
 */
@Slf4j
//@Service
@Component
public class MapLocationService 
    
    //private List<MapLocation> spots = new ArrayList<MapLocation>();

    @Autowired(required = true)
    MapLocationRepository    mapLocationRepository;
    @Autowired(required = true)
    TagDefinitionsRepository tagDefinitionsRepository;
    @Autowired (required = true)
    LinksRepository          linksRepository;
    @Autowired (required = true)
    AddressRepository        addressRepository; 

    public void checkRepositoryStatus () 
        log.warn("checkRepositoryStatus");
        if (mapLocationRepository == null) 
            log.warn("Repository is == NULL!");
         else if (tagDefinitionsRepository == null) 
            log.warn("tagDefnitionsRepository == NULL!!");
        
    

    public void setMapLocationRepository (MapLocationRepository repository) 
        this.mapLocationRepository = repository;
    

    public Repository getMapLocationRepository() 
        return (Repository) mapLocationRepository;
    
    
    @PostConstruct
    private void init() 
        log.info("init called!");
    
    /**
     * Retrieves a list of map locations to the caller. As the
     * map location is lazilly loaded the caller needs to instantiate each object
     * using @link getManagedMapLocation
     * 
     * @return list of map locations.
     */
    @Transactional
    public List<MapLocation> getAll() 
        log.info("getAll");
        //return Collections.unmodifiableList(spots);
        return mapLocationRepository.findAll();
    
    
    @Transactional
    public MapLocation getManagedMapLocation (MapLocation mapLocation) 
        Optional<MapLocation>mapLocationResponse = mapLocationRepository.findById(mapLocation.getId());
        mapLocation = mapLocationResponse.get();
        mapLocation = getAllLinks(mapLocation);
        mapLocation = getAllAddresses(mapLocation);
        mapLocation = getAllTags(mapLocation);
        return mapLocation;
    
    
    @Transactional
    public MapLocation getAllAddresses (MapLocation mapLocation) 
        log.info("getAllAddresses called!");
        mapLocation.getAddresses();
        log.info("Retrieved (" + mapLocation.getAddresses().size() + ") objects in list!");
        return mapLocation;
    
    
    @Transactional
    public MapLocation getAllLinks (MapLocation mapLocation) 
        log.info("getAllLinks called!");
        mapLocation.getLinks();
        log.info("Retrieved (" + mapLocation.getLinks().size() + ") objects in list!");
        return mapLocation;
    
    
    @Transactional
    public MapLocation getAllTags (MapLocation mapLocation) 
        mapLocation.getTagDefinitions();
        return mapLocation;
    

    /**
     * The spot object is a non managed object as returned by this service from
     * the getAllFunction.
     * 
     * @param spot
     */
    @Transactional
    public MapLocation addSpot(MapLocation spot) 
        log.info("addSpot called!");
        MapLocation mapLocation = mapLocationRepository.save(spot);
        for (Links i : spot.getLinks()) 
            log.info("links: " + i.getLink() + " id = " + i.getId());
            i.setMaplocation(mapLocation);
            linksRepository.save(i);
        
        for (Address i : spot.getAddresses()) 
            log.info("Address: " + i.getAddressline1() + " id = " + i.getId());
            i.setMaplocation(mapLocation);
            addressRepository.save(i);
        
        for (TagDefinitions i : spot.getTagDefinitions()) log.info("Tagdefinition: " + i.getTag());
        return mapLocation;
    

    @Transactional
    public void delete (MapLocation mapLocation) 
        /* Implementaion */
        log.info("delete on maplocation is called!");
        for (Links i: mapLocation.getLinks()) 
            log.info("Removing link (" + i.getId() + ")");
            linksRepository.delete(i);
        
        for(Address i : mapLocation.getAddresses()) 
            log.info("Deleting address (" + i.getId() + ")");
            addressRepository.delete(i);
        
        log.info ("remove mapLocation.getId (" + mapLocation.getId() + ")");
        mapLocationRepository.delete(mapLocation);
        /* * * */
    

    /**
     * 
     * @param name Marker name, which should be used on the map.
     * @param links the links associated with the marker
     * @param address the address to the nearest street address
     * @param latitude
     * @param longitude
     * @param tags the list of tag (in string form) for the marker.

     * @return
     */
    public MapLocation prepareSpot (Long                 id,
                                    String               name, 
                                    List<Links>          links,
                                    List<Address>        addresses,
                                    double               latitude,
                                    double               longitude, 
                                    List<TagDefinitions> tagDefinitions) 
        /* Implementation */
        MapLocation mapLocation = new MapLocation();
        mapLocation.setId             (id);
        mapLocation.setName           (name);
        mapLocation.setLinks          (links);
        mapLocation.setAddresses      (addresses);
        mapLocation.setLatitude       (latitude);
        mapLocation.setLongitude      (longitude);
        mapLocation.setTagDefinitions (tagDefinitions);
        mapLocation.setAddresses      (addresses);
        mapLocation.setLinks          (links);

        /* * * */
        return mapLocation;
    

以及合适的领域实体;

package se.poi.restlayer.dblayer.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * Simple data object representing a marker on a map.
 */
@Entity
@Data
@Table(name="MAP_LOCATION")
@AllArgsConstructor
@NoArgsConstructor
public class MapLocation implements Serializable 
    /**
     * 
     */
    private static final long serialVersionUID = -590067472197846904L;
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long   id;
    @Column(name="latitude",    nullable = false)
    private Double latitude;
    @Column(name="longitude",   nullable = false)
    private Double longitude;
    @Column(name="name",        length = 128)
    private String name;
    @ManyToMany (fetch=FetchType.EAGER) //(mappedBy = "mapLocations")
    @JoinTable(name="maplocations_tagdefinitions", 
               joinColumns= @JoinColumn(name="mapLocations"), 
               inverseJoinColumns = @JoinColumn(name="tagDefinitions"))
    private List<TagDefinitions>tagDefinitions = new ArrayList<>();
    @OneToMany(mappedBy="maplocation")
    private List<Links> links;
    @OneToMany(mappedBy="maplocation")
    private List<Address> addresses;

    public MapLocation(double latitude, double longitude, String name, List<TagDefinitions>tagDefinitions) 
        this.latitude       = latitude;
        this.longitude      = longitude;
        this.name           = name;
        this.tagDefinitions = tagDefinitions;
        /* * * */
    


启动它的测试;

package se.poi.restlayer;

import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Test;
//import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import lombok.extern.slf4j.Slf4j;
import se.poi.restlayer.controller.GetTagsController;

/**
 * 
 * @author fmanh
 */
@RunWith(SpringRunner.class)
@WebMvcTest(GetTagsController.class)
@AutoConfigureRestDocs(outputDir="target/snippets")
@Slf4j
public class WebLayerTest 
    @Autowired
    private MockMvc mockMvc;
    @Test
    public void testGetTags() throws Exception 
        log.info ("mockMvc == " + ((this.mockMvc==null)?"NULL":"INSTANTIATED"));
        log.info("KALLE");
        this.mockMvc.perform (get("/retrievealltags")); //.
        //andExpect(status().isOk()).
        //andExpect(content().json("")).
        //andDo(print()).
        //andDo(document("/retrievealltags"));
    


application.properties

server.port=8080

# Ensure application is run in Vaadin 14/npm mode

vaadin.compatibilityMode     = false

logging.level.org.atmosphere = warn

#
# Settings for the internal H2
#
#spring.datasource.url             = jdbc:h2:file:~/test
#spring.datasource.driverClassName = org.h2.Driver
#spring.datasource.username        = sa
##spring.datasource.password       =
#spring.jpa.databse-platform       = org.hibernate.dialect.H2Dialect
#spring.h2.console.enabled         = true
#spring.h2.console.path            = /h2-console
#hibernate.dialect                 = H2

#
# Set up the postgres database
#
spring.datasource.url                               = jdbc:postgresql://localhost:5432/postgres 
spring.datasource.username                          = postgres
spring.datasource.password                          = d1d4a5baa55f4f70a90e12bc95473833
spring.jpa.database-platform                        = org.hibernate.dialect.PostgreSQL94Dialect
spring.jpa.show-sql                                 = true
spring.jpa.hibernate.ddl-auto                       = update
spring.jpa.hibernate.naming.implicit-strategy       = org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
spring.jpa.properties.hibernate.format_sql          = true

spring.jpa.properties.hibernate.generate_statistics = true

logging.level.org.hibernate.type=trace
logging.level.org.hibernate.stat=debug

#spring.jpa.hibernate.ddl-auto=none
# Following values available;
# validate, update, create, create-drop, none

#server.port                   = 8443
#server.ssl.key-store-type     = PKCS12
#server.ssl.key-store          = classpath:keystore.p12
#server.ssl.key-store-password = Pur3Life
#server.ssl.key-alias          = tomcat
#security.require-ssl          = true

感谢任何帮助!我试过谷歌它是徒劳的(也许我的谷歌 fu 没有达到标准,或者我错过了一些明显的东西),如果是这样,请随时指出。软件的 tar 存档 如果您愿意,可以获取 e(这里没有秘密)。请帮助我在这里增长一点智慧!

编辑!

我意识到我的描述不完整:我的解决方案包含一个包含以下控制器的 restlayer;

package se.poi.restlayer.controller;

import java.util.ArrayList;
import java.util.List;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import se.poi.dblayer.ConfigurationDbLayer;
import se.poi.dblayer.domain.Address;
import se.poi.dblayer.domain.Links;
import se.poi.dblayer.domain.MapLocation;
import se.poi.dblayer.domain.TagDefinitions;
import se.poi.dblayer.repositories.AddressRepository;
import se.poi.dblayer.services.MapLocationService;
import se.poi.dblayer.services.TagDefinitionsService;
import se.poi.restlayer.model.AddressObject;
import se.poi.restlayer.model.LinkObject;
import se.poi.restlayer.model.MapLocationList;
import se.poi.restlayer.model.MapLocationObject;
import se.poi.restlayer.model.TagDefinitionObject;
import se.poi.restlayer.model.TagDefinitionsList;

/**
 * The 
 * @author Joakim Hansson
 */
@RestController
//@EnableJpaRepositories(basePackages="se.poi.dblayer.repositories")
//@EntityScan(basePackages="se.poi.dblayer.domain")
//@ComponentScan(basePackages="se.poi.dblayer.services", "se.poi.dblayer.repositories")
@Slf4j
//@Import(value=ConfigurationDbLayer.class)
public class GetTagsController 
    //@Autowired
    //AddressRepository a;
    @Autowired
    TagDefinitionsService tagDefinitionService;
    //@Autowired
    MapLocationService mapLocationService;
    //private TagDefinitionsService tagDefinitionService = new TagDefinitionsService ();
    //private MapLocationService    mapLocationService   = new MapLocationService    ();

    @GetMapping("/retrievealltags")
    public TagDefinitionsList retrieveAllTags () 
        /* Implementation */
        if (tagDefinitionService==null) log.error ("tagDefinitionsService: NULL!");
        List<TagDefinitions> list = tagDefinitionService.getAllTagDefinitionsInFull();

        TagDefinitionsList tagDefinitionsList  = new TagDefinitionsList();
        ArrayList<TagDefinitionObject> tagDefinitions = new ArrayList<TagDefinitionObject>();

        for (TagDefinitions item : list) 
            TagDefinitionObject tagDefinition = new TagDefinitionObject ();

            tagDefinition.setId          (item.getId());
            tagDefinition.setDescription (item.getDescription());
            tagDefinition.setTag         (item.getTag());
            tagDefinition.setParentId    (null);

            tagDefinitions.add           (tagDefinition);
        

        tagDefinitionsList.setTagDefinitions(tagDefinitions);

        /* * * */
        return tagDefinitionsList;
    
    
    @GetMapping("/retrieveMarkers")
    public MapLocationList retrieveMarkers () 
        /* Implementation */
        // Retrieve all the data from the service...
        List<MapLocation> l = mapLocationService.getAll();

        // Convert to...
        MapLocationList mapLocationList = new MapLocationList ();
        ArrayList<MapLocationObject> ll = new ArrayList<MapLocationObject> ();

        for (MapLocation item: l) 
            MapLocationObject mapLocationObject = new MapLocationObject ();

            mapLocationObject.setId        (item.getId        ());
            mapLocationObject.setLatitude  (item.getLatitude  ());
            mapLocationObject.setLongitude (item.getLongitude ());
            mapLocationObject.setName      (item.getName      ());
            mapLocationObject.setLinks     (copyLinksList     (item.getLinks     ()));
            mapLocationObject.setAddresses (copyAddressList   (item.getAddresses ()));

            ll.add (mapLocationObject);
        
        /* * * */
        return mapLocationList;
    

    /* Private functions
     * **********************************************************************/
    /**
     * Copies data from the database model to the rest API model.
     * 
     * @param links
     * @return
     */
    private List<LinkObject> copyLinksList (List<Links>links) 
        /* Implementation */
        ArrayList<LinkObject> ll = new ArrayList<LinkObject> ();

        for (Links item: links) 
            LinkObject linkObject = new LinkObject();

            linkObject.setId   (item.getId());
            linkObject.setLink (item.getLink());

            ll.add(linkObject);
        
        /* * * */
        return ll;
    
    
    /**
     * 
     * @param address
     * @return
     */
    private List<AddressObject> copyAddressList (List<Address>address) 
        /* Implementation */
        ArrayList<AddressObject> ll = new ArrayList<AddressObject> ();

        for (Address item: address) 
            AddressObject addressObject = new AddressObject();

            addressObject.setId           (item.getId           ());
            addressObject.setAddressline1 (item.getAddressline1 ());
            addressObject.setAddressline2 (item.getAddressline2 ());
            addressObject.setAddressline3 (item.getAddressline3 ());
            addressObject.setCity         (item.getCity         ());
            addressObject.setPostcode     (item.getPostcode     ());

            ll.add(addressObject);
        
        /* * * */
        return ll;
    


这意味着应用程序尝试实例化一个控制器,该控制器在 dblayer 服务上包含一个自动装配注释,而这个 dblayer 服务又在存储库上包含一个自动装配注释。正是这条链向南。很抱歉遗漏了。

编辑; 我现在正在广泛尝试;自动接线根本不起作用。叹!。有趣的是,我可以在我的日志文件中看到找到了 4 个 jpa 实体,但我根本无法使用 Autowired 来处理这些存储库......谷歌接缝指出这是一个常见问题,但似乎没有成为一个明确的解决方案。

【问题讨论】:

你有@EntityScan 和@EnableJpaRepositories 有什么原因吗?为什么你的包装是这样分层的? 当前的分层只是为了让事物正常运行而进行的实验。我的意图是将它拆分为一个特定的模块(即 dblayer 中的所有内容都应该在它自己的模块中,以及一个配置类)。然后我的主应用程序类将导入模块。我使用注释来特别指出目录仅仅是因为我没有让事情正常工作,我开始尝试。 【参考方案1】:

您正在为 SpringBoot 和 JPA 使用不同的版本(这是错误的,您总是让 SpringBoot 为所有 SpringBoot 启动器拉取版本)- 删除此行

 <version>2.3.1.RELEASE</version>

来自 JPA 依赖项,以便 Spring Boot 从父级中提取正确的版本,并让我知道问题是否仍然存在。

【讨论】:

我的导入语句现在看起来像; &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt; &lt;!--version&gt;2.3.1.RELEASE&lt;/version--&gt; &lt;/dependency&gt; 即我删除了版本字段。还是不行。服务中根本不会发生 Autowire。 我已经得出结论,这是一个测试问题。每当我以独立模式启动应用程序时,一切正常。但是我的测试设置完全搞砸了,并且经常拒绝自动接线。 我也有同样的想法,但不确定 - 您使用的是 @RunWith(SpringRunner.class),这是使用 Junit 4 设置 SpringTests 的方式,但我可以通过导入看到您拥有 Junit Jupiter(即下一个版本)作为您的依赖项。在该测试中,您不需要该注释,因此只需将其删除。 @MockMvcTest 就够了。 非常感谢您的输入 Asgarov,正如我所说,我正在尝试在这里尽可能多地学习。我将很快将完整的代码添加到公共存储库(它的价值)作为 GPL 项目(这是一个学习工具,在任何方面都没有重大或革命性)。我会带着新的观察回来。再次感谢!

以上是关于关于 JPA 存储库和自动装配的 Java spring 问题的主要内容,如果未能解决你的问题,请参考以下文章

wicket,spring jpa存储库 - @Autowire上的nullpointer

尽管有 @EnableJpaRepositories 注释,但 Spring JPA 未实现/自动装配存储库

在 Spring Boot 应用程序的 JUnit 测试中,自动装配的 JPA 存储库没有合格的 bean

如何在 Spring Boot 中实现通用 JPA 存储库 - 它可以自动装配到任何实体/类类型的 Spring 服务中

自动装配到 JPA 转换器中

使用 Spring Boot 自动装配具有 jpa 和非 jpa 特征的多个数据源