spring cloud使用JpaRepository,dao层无法注入容器,调试报空指针的解决思路

编程入门 行业动态 更新时间:2024-10-25 18:35:13

spring cloud使用JpaRepository,dao层无法注入容器,调试报空<a href=https://www.elefans.com/category/jswz/34/1768268.html style=指针的解决思路"/>

spring cloud使用JpaRepository,dao层无法注入容器,调试报空指针的解决思路

     公司岗位调整,我从一个安卓开发转后台开发,以前在其他公司也接触过后台,那时公司用的是ssm框架,不过安卓还是
主业务,后台业务也只是略而兼之,并未深研,想着公司这次给机会做后台,本着技多不压身,就欣然接受,此时已经2019年了,微服务方兴未艾,如火如荼,自然我也就去学习微服务了,在学习过程中,spring cloud使用JpaRepository,编译是能通过,在调试接口时报了一个空指针,经过debug调试,是接口

public interface ProductInfoRepository extends JpaRepository<ProductInfo, String> {List<ProductInfo> findByProductStatus(List<String> productIdStatus);}

 在下面的service中

@Service
public class ProductInfoServiceImpl implements IProductInfoService {@Autowired(required = false)private ProductInfoRepository productInfoRepository;@Overridepublic List<ProductInfo> getProductList() {List<String> integerList = new ArrayList<>();integerList.add("1");List<ProductInfo> productInfoList = productInfoRepository.findByProductStatus(integerList);return productInfoList;}
}


      其中private ProductInfoRepository productInfoRepository是null的,ProductInfoRepository没有注入到容器中
调试几遍还是报空指针,只好求助百度,可以说困扰了我4天,都没有找到spring cloud使用JpaRepository报空指针的解决方案
网上找到的以下方案,都试了,都无用
1.private ProductInfoRepositoryproductInfoRepository是不是没有用@Autowired(required = false)注解,检查自己写的代码,是注解了
2.public interface ProductInfoRepository加上@Component,@Repository, 加上后,调试结果,service中的productInfoRepository还是为null,继续报空指针
3.controller和service中的方法是不是private的,检查自己的代码,方法都是public,排除该怀疑对象
4.entity实体类加上@table,@colum,调试结果,service中的productInfoRepository还是为null,报空指针
5.甚至自己怀疑是不是(required = false)了,去掉该配置,自然就报了另外一个异常,方案还是不对
6.Application上加上

@ComponentScan(basePackages = {"com.chengfeng.product.controller","com.chengfeng.product.service"}),
@EntityScan(basePackages = "com.chengfeng.product.entity")
@EnableJpaRepositories(basePackages = "com.chengfeng.product.repository")

即代码为


@SpringBootApplication()(exclude = DataSourceAutoConfiguration.class)
@EnableDiscoveryClient
@ComponentScan(basePackages = {"com.chengfeng.product.controller","com.chengfeng.product.service"}),
@EntityScan(basePackages = "com.chengfeng.product.entity")
@EnableJpaRepositories(basePackages = "com.chengfeng.product.repository")
public class ProductApplication {public static void main(String[] args) {SpringApplication.run(ProductApplication.class, args);}}


上述加上,调试结果,service中的productInfoRepository还是为null,报空指针,
7.检查定义的entity实体类ProductInfo中的属性字段是否与数据库中一致,一一检查,都一一对应,排除该怀疑对象
8.当然什么重启了,清除缓存,说jar包冲突的,把原来的jar包全部清除重新下载,依然无用。
说实话,搞了几天都快崩溃了,放弃心又不甘,元气恢复,又鬼使神差继续调试。
9.是不是new service对象或者new  ProductInfoRepository对象了,检查自己的代码,也排除该怀疑对象
10.最后实在没有脾气了,把ProductInfoRepository定义的接口屏蔽掉,用JpaRepository原生生成的默认方法,还是报空指针。

最后,看了一眼ProductApplication 

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableDiscoveryClient
public class ProductApplication {public static void main(String[] args) {SpringApplication.run(ProductApplication.class, args);}
}


死马当活马医,把(exclude = DataSourceAutoConfiguration.class)去掉,将原来出现的

Error creating bean with name 'entityManagerFactory' defined in class path resource[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]

异常暴露出来,把这个问题解决,看能不能顺便把空指针解决,然而运行后先报

HHH000342: Could not obtain connection to query metadata : Driver com.mysql.cj.jdbc.Driver claims to not accept jdbcUrl, 
jdbc:mysql:http://localhost:3306/product?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC

了一个新的问题,再报

 Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException:Error creating bean with name 'entityManagerFactory' defined in class path resource[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.service.spi.ServiceException:Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]


 根据网上资料,application.properties中的spring.datasource.***肯定有问题,仔细看了几遍application.properties:

spring.application.name=productserver.port=8081
eureka.client.service-url.defaultZone: http://localhost:8761/eureka/spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
spring.datasource.url= jdbc:mysql:http://localhost:3306/product?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
spring.datasource.username = root
spring.datasource.password = 123456spring.jpa.hibernate.ddl-auto = update# 方便jpa调试的配置
spring.jpa.show-sql = true

也没发现什么问题,最后经过对比,发现jdbc:mysql后面多了个http,之前没有开发配置过数据库,也不知这里到底如何配置,什么时候这里多了个http,难道是因为多了个http,抱着疑问的态度改成

spring.datasource.url= jdbc:mysql://localhost:3306/product?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC


 奇迹出现了,项目成功运行起来,最后接口调试,service中的productInfoRepository也成功注入容器了了,接口也调通了,也不报空指针了。此刻我已经知道,肯定是ProductInfoRepository中的接口写的不符合jpa规范,所以才造成ProductInfoRepository不能成功注入容器,将原来的方法:

// List<ProductInfo> findByProductStatus(List<String> productIdStatus);


 放开,运行,果然是又报错,

@SpringBootApplication加上(exclude = DataSourceAutoConfiguration.class),运行项目,错误消失,接口调试,继续报空指针,
至于为什么这个方法造成jpa不能注入容器,想必是这种接口定义方法不符合jpa规范,jpa识别不了。

最终,spring cloud使用jpa,要避免Repository不能注入容器,防止空指针的发生,除了排除上述10点怀疑对象,还要注意以下3点:

(1)@SpringBootApplication不能加(exclude = DataSourceAutoConfiguration.class)

(2)application.properties中关于数据库的配置一定要准确

(3)继承JpaRepository的dao层接口中自己定义的方法一定要符合jpa规范,按jpa的提示定义相关防范,不要自己随意命名,

最后附上spring cloud demo的部分

pom.xml代码

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".0.0" xmlns:xsi=""xsi:schemaLocation=".0.0 .0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.1.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.chengfeng</groupId><artifactId>product</artifactId><version>0.0.1-SNAPSHOT</version><name>product</name><description>Demo project for Spring Boot</description><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><spring-cloud.version>Hoxton.RC2</spring-cloud.version></properties><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>;/url></repository></repositories></project>

application.properties代码:

spring.application.name=productserver.port=8081
eureka.client.service-url.defaultZone: http://localhost:8761/eureka/spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
spring.datasource.url= jdbc:mysql://localhost:3306/product?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
spring.datasource.username = root
spring.datasource.password = 123456spring.jpa.hibernate.ddl-auto = update# 方便jpa调试的配置
spring.jpa.show-sql = true
package com.chengfeng.product;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication
@EnableDiscoveryClient
public class ProductApplication {public static void main(String[] args) {SpringApplication.run(ProductApplication.class, args);}}

 controller层ProductController.java代码

package com.chengfeng.product.controller;@RestController
@RequestMapping("/product")
public class ProductController {@Autowiredprivate IProductInfoService productInfoService;@GetMapping("/list")public void getProductList() {System.out.println("开始获取getProductList");//  1.查询所有商品List<ProductInfo> productInfoList = productInfoService.getProductList();System.out.println("获取的getProductList == ",productInfoList);}
}

Entity实体类ProductInfo.java代码

package com.chengfeng.product.entity;import javax.persistence.Entity;
import javax.persistence.Id;
import java.math.BigDecimal;
import java.util.Date;/*** 这里表名会自动转换,数据库中驼峰会是下划线,下面的变量也是*/@Entity
public class ProductInfo {@Idprivate String productId;/** 名字. */private String productName;/** 单价. */private BigDecimal productPrice;/** 库存. */private Integer productStock;/** 描述. */private String productDescription;/** 小图. */private String productIcon;/** 状态, 0正常1下架. */private Integer productStatus;/** 类目编号. */private Integer categoryType;private Date createTime;private Date updateTime;public String getProductId() {return productId;}public void setProductId(String productId) {this.productId = productId;}public String getProductName() {return productName;}public void setProductName(String productName) {this.productName = productName;}public BigDecimal getProductPrice() {return productPrice;}public void setProductPrice(BigDecimal productPrice) {this.productPrice = productPrice;}public Integer getProductStock() {return productStock;}public void setProductStock(Integer productStock) {this.productStock = productStock;}public String getProductDescription() {return productDescription;}public void setProductDescription(String productDescription) {this.productDescription = productDescription;}public String getProductIcon() {return productIcon;}public void setProductIcon(String productIcon) {this.productIcon = productIcon;}public Integer getProductStatus() {return productStatus;}public void setProductStatus(Integer productStatus) {this.productStatus = productStatus;}public Integer getCategoryType() {return categoryType;}public void setCategoryType(Integer categoryType) {this.categoryType = categoryType;}public Date getCreateTime() {return createTime;}public void setCreateTime(Date createTime) {this.createTime = createTime;}public Date getUpdateTime() {return updateTime;}public void setUpdateTime(Date updateTime) {this.updateTime = updateTime;}
}

dao层ProductInfoRepository.java代码

package com.chengfeng.product.repository;import com.chengfeng.product.entity.ProductInfo;
import org.springframework.data.jpa.repository.JpaRepository;import java.util.List;public interface ProductInfoRepository extends JpaRepository<ProductInfo, String> {List<ProductInfo> findByProductStatus(Integer productStatus);
}

服务层ProductInfoServiceImpl.java代码

package com.chengfeng.product.service;import com.chengfeng.productmon.ProductStatusEnum;
import com.chengfeng.product.entity.ProductInfo;
import com.chengfeng.product.repository.ProductInfoRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;@Service
public class ProductInfoServiceImpl implements IProductInfoService {@Autowired(required = false)private ProductInfoRepository productInfoRepository;@Overridepublic List<ProductInfo> getProductList() {List<ProductInfo> productInfoList = productInfoRepository.findByProductStatus(ProductStatusEnum.UP.getCode());return productInfoList;}
}

 

更多推荐

spring cloud使用JpaRepository,dao层无法注入容器,调试报空指针的解决思路

本文发布于:2024-02-25 05:01:01,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1697886.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:指针   容器   思路   cloud   spring

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!