Spring Boot创建Bean报错及无实体调用Oracle存储过程问题咨询
问题1:Bean创建错误解决方案
错误根因如下:
- 你的
OeeDao作为JPA Repository接口,继承JpaRepository<Object,Integer>时,第一个泛型参数要求必须是被@Entity注解修饰的JPA托管实体类,Object不属于托管实体,直接触发Not a managed type: class java.lang.Object错误 - JPA Repository本身是接口规范,Spring Data JPA会自动为接口生成代理实现类,不支持在接口中直接注入
EntityManager、编写方法实现逻辑 - Swagger依赖版本不匹配:
springfox-swagger2用3.0.0版本,springfox-swagger-ui用2.9.2版本,版本不一致会引发额外启动问题
修复步骤:
- 废弃原有继承JpaRepository的OeeDao接口,改为编写普通DAO实现类
package level3.reports.dataAccess.concretes; import java.math.BigDecimal; import java.util.Date; import jakarta.persistence.EntityManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @Repository public class OeeDao { private final EntityManager entityManager; @Autowired public OeeDao(EntityManager entityManager) { this.entityManager = entityManager; } public BigDecimal A1AfterReworkRatio(int V_plant_config_num_id, Date p_start_date, Date p_stop_date) { // 修复原有SQL的参数分隔符错误:参数之间用逗号分隔,不是冒号 BigDecimal commentCount = (BigDecimal) entityManager .createNativeQuery( "SELECT Z_OEE_A1AfterReworkRatio(:V_plant_config_num_id,:p_start_date,:p_stop_date) FROM DUAL" ) .setParameter("V_plant_config_num_id", V_plant_config_num_id) .setParameter("p_start_date", p_start_date) .setParameter("p_stop_date", p_stop_date) .getSingleResult(); return commentCount; } }
- 修改Service层的依赖注入逻辑适配新的OeeDao
package level3.reports.business.concretes; import java.math.BigDecimal; import java.util.Date; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import level3.reports.business.abstracts.OeeReportService; import level3.reports.dataAccess.concretes.OeeDao; @Service public class OeeReportManager implements OeeReportService { private final OeeDao oeeDao; @Autowired public OeeReportManager(OeeDao oeeDao) { this.oeeDao = oeeDao; } @Override public int A1AfterReworkRatio(int V_plant_config_num_id,Date p_start_date,Date p_stop_date) { BigDecimal result = this.oeeDao.A1AfterReworkRatio(V_plant_config_num_id,p_start_date,p_stop_date); // 增加空值判断避免空指针 return result != null ? result.intValue() : 0; } }
- 统一Swagger依赖版本,推荐使用3.0.0官方starter,替换原有两个零散Swagger依赖
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>3.0.0</version> </dependency>
升级后Swagger访问地址为 http://localhost:8080/swagger-ui/index.html
问题2:无实体直接调用Oracle存储过程/函数的方案
不需要继承JpaRepository,直接依赖EntityManager的原生查询能力即可实现无实体调用,两种常见场景实现方式:
- 调用函数:就是上文修复后的
createNativeQuery查DUAL表的方式,不需要绑定任何实体,直接接收返回值即可 - 调用存储过程:使用
createStoredProcedureQuery方法实现,示例如下
import jakarta.persistence.ParameterMode; public void callCustomProcedure(int inputParam) { entityManager.createStoredProcedureQuery("你的存储过程名") // 注册入参 .registerStoredProcedureParameter("入参名", Integer.class, ParameterMode.IN) // 注册出参(如果有) .registerStoredProcedureParameter("出参名", String.class, ParameterMode.OUT) .setParameter("入参名", inputParam) .execute(); // 获取出参 String output = (String) storedProcedureQuery.getOutputParameterValue("出参名"); }
如果需要返回多结果集,直接调用getResultList()接收,返回值为List<Object[]>,不需要映射实体,自行解析数组内容即可。
内容的提问来源于stack exchange,提问作者Hakan özel
相关产品推荐
相关产品推荐

