在Spring Boot中使用@Autowired注入Spring Data JPA Repository失败

3

Spring Boot入口类

package com.test;

@SpringBootApplication(exclude={
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class})
public class AssetManagementDigital2Application {

    public static void main(String[] args) {
        SpringApplication.run(AssetManagementDigital2Application.class, args);
    }
}

控制器类

package com.test.assetmanagementdigital.controller;

 @RestController

public class ShopController {

    @Autowired
    private ShopServiceImpl shopServiceImpl;

    @RequestMapping(value="/shops",method=RequestMethod.POST)
    public void shopDetails(Shop shop){
        shopServiceImpl.addShopDetails(shop);

    }

}

实体

package com.test.assetmanagementdigital.model;

import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name="ShopDetails")
public class Shop {

    private String shopName;
    private Address address;

    public String getShopName() {
        return shopName;
    }

    public void setShopName(String shopName) {
        this.shopName = shopName;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }


}

Data JPA Repository接口

package com.test.assetmanagementdigital.repository;
    @Repository
    public interface ShopRepository extends CrudRepository<Shop,Long>{

    }

服务类

package com.test.assetmanagementdigital.service;
@Service
public class ShopServiceImpl {

    @Autowired
    private ShopRepository shopRepository;

    public void addShopDetails(Shop shop) {
        shopRepository.save(shop);
    }

}

gradle file

 buildscript {
        ext {
            springBootVersion = '2.0.0.BUILD-SNAPSHOT'
        }
        repositories {
            mavenCentral()
            maven { url "https://repo.spring.io/snapshot" }
            maven { url "https://repo.spring.io/milestone" }
        }
        dependencies {
            classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        }
    }

    apply plugin: 'java'
    apply plugin: 'eclipse-wtp'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'
    apply plugin: 'war'

    version = '0.0.1-SNAPSHOT'
    sourceCompatibility = 1.8

    repositories {
        mavenCentral()
        maven { url "https://repo.spring.io/snapshot" }
        maven { url "https://repo.spring.io/milestone" }
    }

    configurations {
        providedRuntime
    }

    dependencies {
        compile('org.springframework.boot:spring-boot-starter-data-jpa')
        compile('org.springframework.boot:spring-boot-starter-web')
        compile("com.h2database:h2")
        compile group: 'org.hibernate', name: 'hibernate-core', version: '4.2.2.Final'
        providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
        testCompile('org.springframework.boot:spring-boot-starter-test')
    }

我遇到了以下错误:
Description:

Field shopRepository in com.test.assetmanagementdigital.service.ShopServiceImpl required a bean of type 'com.test.assetmanagementdigital.repository.ShopRepository' that could not be found.

Action:

Consider defining a bean of type 'com.test.assetmanagementdigital.repository.ShopRepository' in your configuration.

如果我从ShopRepository中移除@Autowired注释,那么它会抛出'NullPointerException'

我已经尝试在这里使用@EnableJpaRepositories("com.test.assetmanagementdigital.repository"),但是我得到了

org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'shopController': Unsatisfied dependency expressed through field 'shopServiceImpl'; nested exception is 
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'shopServiceImpl': Unsatisfied dependency expressed through field 'shopRepository'; nested exception is 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'shopRepository': Post-processing of merged bean definition failed; nested exception is 
java.lang.NoSuchMethodError: javax.persistence.PersistenceContext.synchronization()Ljavax/persistence/SynchronizationType;

我认为缺少@Transactional注解。 - soorapadman
1
你的依赖关系有误(这就是最后一个堆栈跟踪/错误告诉你的)。请添加你的pom文件或gradle文件。 - M. Deinum
Gradle文件已添加。 - kiran rathod
移除已经通过 spring-boot-starter-data-jpa 添加的 hibernate-core 依赖。您添加的版本是旧版本,与 starter 中包含的版本冲突。简单的解决方案就是移除 hibernate-core 依赖。 - M. Deinum
这是真的,移除了 hibernate-core 依赖后上述错误消失了,但是出现了新的错误。 - kiran rathod
感谢您的帮助 :) - kiran rathod
2个回答

6
您的Spring配置不正确。
spring-boot-starter-data-jpa已经提供了hibernate-core的依赖项。您声明它时指定了一个特定的版本:
compile group: 'org.hibernate', name: 'hibernate-core', version: '4.2.2.Final'

您不需要第二次声明它,因为您指定的版本可能与起始器提供的版本不兼容。根据您的错误,似乎是这种情况,因为在运行时找不到javax.persistence.PersistenceContext.synchronization()方法。
合并的bean定义后处理失败;嵌套异常是java.lang.NoSuchMethodErrorjavax.persistence.PersistenceContext.synchronization()Ljavax/persistence/SynchronizationType
只需删除hibernate-core依赖项,就可以解决问题。

1
在Spring Boot应用程序中,您不需要使用@EnableJpaRepositories。Spring Boot会自动检测Spring Data JPA(和其他数据源),并为其配置适当的@Enable*Repositories - M. Deinum
@M. Deinum,您是完全正确的。我修改了我的答案。感谢您确保良好的质量内容。 - davidxxx

-1

你需要提供包名给Spring,使用@EnableJpaRepositories注解来扫描仓库,例如:

@SpringBootApplication
@EnableJpaRepositories("com.test.assetmanagementdigital.repository")
public class AssetManagementDigital2Application

这里是文档。


我已经编辑了上面的问题,请检查,并且之前也尝试过这个。 - kiran rathod
1
在Spring Boot应用程序中,您不需要使用“@EnableJpaRepositories”。Spring Boot会自动检测Spring Data JPA(以及其他组件)并为其配置适当的“@Enable*Repositories”。 - M. Deinum
@kiranrathod 请问为什么 DataSourceAutoConfiguration 被禁用了? - Darshan Mehta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接