GRPC服务构造实例报错,无注解仓库及EntityManagerFactory问题求助
一、gRPC服务类手动实例化依赖的问题
你的ServiceCategoryImpl作为Spring管理的@Service,却手动通过new CategoryCommandServiceImpl()实例化依赖,这会导致CategoryCommandServiceImpl内部的Spring依赖(比如CategoryRepository)无法被注入,进而出现repository is null的错误——Spring不会管理你手动new出来的对象,自然不会帮你注入它的依赖。
解决办法:
- 给
CategoryCommandServiceImpl添加@Service注解,让Spring接管这个类的实例化 - 修改
ServiceCategoryImpl的构造函数为依赖注入模式,不再手动new:
@Service public class ServiceCategoryImpl extends CategoryProductGrpc.CategoryProductImplBase { private final CategoryCommandServiceImpl categoryCommand; // 构造函数注入,Spring自动传入CategoryCommandServiceImpl实例 public ServiceCategoryImpl(CategoryCommandServiceImpl categoryCommand){ this.categoryCommand = categoryCommand; } }
二、EntityManagerFactory找不到Persistence Provider的问题
你遇到的jakarta.persistence.PersistenceException: No Persistence provider for EntityManager named category错误,常见原因及解决方式如下:
1. 缺少persistence.xml配置文件
JPA要求在src/main/resources/META-INF目录下创建persistence.xml,且需配置名称为category的persistence-unit,并指定Persistence Provider(如Hibernate)。示例配置:
<?xml version="1.0" encoding="UTF-8"?> <persistence version="3.0" xmlns="https://jakarta.ee/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"> <persistence-unit name="category" transaction-type="RESOURCE_LOCAL"> <!-- 指定Hibernate作为JPA实现 --> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <!-- 关联实体类 --> <class>com.yourpackage.Category</class> <!-- 数据库连接配置 --> <properties> <property name="jakarta.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/> <property name="jakarta.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/your_db"/> <property name="jakarta.persistence.jdbc.user" value="root"/> <property name="jakarta.persistence.jdbc.password" value="your_password"/> <!-- Hibernate方言 --> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/> <!-- 可选:自动更新表结构 --> <property name="hibernate.hbm2ddl.auto" value="update"/> </properties> </persistence-unit> </persistence>
2. 缺少JPA Provider依赖
如果是Maven项目,需在pom.xml中添加Hibernate(或其他JPA实现)的依赖:
<!-- Hibernate核心依赖 --> <dependency> <groupId>org.hibernate.orm</groupId> <artifactId>hibernate-core</artifactId> <version>6.4.4.Final</version> </dependency> <!-- MySQL驱动(根据你的数据库选择) --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.0.33</version> <scope>runtime</scope> </dependency>
3. 无需手动实现Repository
实际上你完全不需要自己编写CategoryRepositoryImpl——Spring Data JPA会自动实现CategoryRepository接口(包括你自定义的findBySlug方法),只需满足以下条件:
- 确保
CategoryRepository接口在Spring的扫描路径内 - 给
Category实体类添加@Entity、@Id等JPA注解 - 在
CategoryCommandServiceImpl中直接注入CategoryRepository使用:
@Service public class CategoryCommandServiceImpl { private final CategoryRepository categoryRepository; public CategoryCommandServiceImpl(CategoryRepository categoryRepository) { this.categoryRepository = categoryRepository; } // 直接调用categoryRepository.findBySlug(slug)即可 }
这种方式既不用手动编写EntityManager相关代码,也能避免依赖注入的问题。
内容的提问来源于stack exchange,提问作者Rafael Souza

