Java Spring 引导项目 returns 中的存储过程 null 作为输出

Stored Procedure in Java Spring Boot Project returns null as Output

我在 Spring 引导项目中使用存储过程并尝试获取输出值,但在我的项目中它始终 returns 为空。但是,如果我通过 HeidiSQL 调用该过程,它会工作并为我提供正确的值。

所以它必须用我的 java 代码做一些事情。我调试了受影响的方法,但找不到它 returns null.

的原因

我已经尝试查找其他帖子,但找不到与我的具体问题相匹配的内容。

这是我尝试使用存储过程的方法:

CompanyResourceServiceImpl

@Service
public class CompanyResourceServiceImpl implements CompanyResourceService {

@PersistenceContext
    private EntityManager entityManager;

...

private int getMetalResourceByPlayerId(int theId) {

        StoredProcedureQuery theQuery = entityManager.createStoredProcedureQuery("getAllMetalFromCompaniesByPlayerId");

        theQuery.registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN);
        theQuery.registerStoredProcedureParameter(2, BigDecimal.class, ParameterMode.OUT);

        theQuery.setParameter(1, theId);

        theQuery.execute();

        BigDecimal outAmount = (BigDecimal) theQuery.getOutputParameterValue(2);

        return outAmount.intValue();
    }

...

}

存储过程如下:

getAllMetalFromCompaniesByPlayerId

CREATE DEFINER=`root`@`localhost` PROCEDURE `getAllMetalFromCompaniesByPlayerId`(
    IN `playerId` INT,
    OUT `metalSum` DECIMAL(19,2)
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
SELECT sum(cr.amount) as metalSum
FROM company_resource cr
JOIN company c ON (c.id = cr.company_id) WHERE c.player_id = playerId and cr.resource_id = 1;
END

我的目标是获取输出值并在 @Scheduled 方法中使用它。 正如我所说,在 HeidiSQL 中,存储过程有效。

经过几个小时的尝试,我找到了一种让它工作的方法。

首先我将 @NamedStoredProcedureQuery 添加到我的 CompanyResource 实体 class:

CompanyResource.java

@Entity
@Table(name = "company_resource")
@NamedStoredProcedureQueries({
        @NamedStoredProcedureQuery(name = "getAllMetalFromCompaniesByPlayerId",
                                    procedureName = "getAllMetalFromCompaniesByPlayerId",
                                    parameters = {
                                        @StoredProcedureParameter(mode = ParameterMode.IN, name = "playerId", type = Integer.class),
                                        @StoredProcedureParameter(mode = ParameterMode.OUT, name = "metalSum", type = BigDecimal.class)
                                    })
})
@IdClass(CompanyResourcePK.class)
public class CompanyResource {
...
}

然后我在 CompanyResourceServiceImpl 中更改了我的 getMetalResourceByPlayerId() 方法如下:

CompanyResourceServiceImpl.java

@Service
public class CompanyResourceServiceImpl implements CompanyResourceService {

@PersistenceContext
    private EntityManager entityManager;

...

private int getMetalResourceByPlayerId(int theId) {

        StoredProcedureQuery theQuery = entityManager.createNamedStoredProcedureQuery("getAllMetalFromCompaniesByPlayerId");

        theQuery.setParameter("Param1", theId);

        BigDecimal outAmount = (BigDecimal) theQuery.getSingleResult();

        return  outAmount.intValue();
    }

...

}