在不使用休眠状态的情况下调用存储的函数

时间:2018-08-10 14:08:42

标签: java jpa-2.1 stored-functions

我的目标是使用@NamedNativeQuery批注调用oracle存储函数。我已经做了大量的研究,但是如果没有其他工具(如TopLink或Hibernate),我找不到关于调用存储函数的任何好的文档。似乎没有一种用于存储函数和存储过程的方法。我认为可能存在一种通用的处理方式,将SELECT F(x)FROM DUAL包装在查询中,然后以我尝试在此处进行的方式进行调用。我可以对如何处理或是否必须采用其他方法有所了解。

这是我要处理的功能:

FUNCTION get_std_rods (p_series_ind IN varchar2, p_style_ind IN varchar2, p_material_ind IN varchar2, p_color_ind IN varchar2)
return SYS_REFCURSOR IS lref SYS_REFCURSOR;
BEGIN
  OPEN lref FOR
    SELECT bbv.default_rod_mat, bbv.default_rod_color
    FROM xxlt.xxlt_bpg_belt_val bbv
    WHERE bbv.series_ind = p_series_ind AND
          bbv.belt_style_ind = p_style_ind AND
          bbv.material_ind = p_material_ind AND
          bbv.color_ind = p_color_ind AND
          bbv.inactive = 0;
  RETURN lref;
END;

在我的模型中,我有以下内容:

@Dependent
@PersistenceUnit(name="DB")
@NamedNativeQuery(name = "get_std_rods", query = "SELECT 
xxlt.xxlt_bpg_std_width_pkg.get_ 
std_rods(:p_series_ind,:p_style_ind,:p_material_ind,:p_color_ind) FROM 
DUAL", resultClass = StandardRods.class)
@Produces("application/json")
@Entity

这是我的存储库类:

@Dependent
public class StandardRodsRepo implements StandardRodsDAO{
@PersistenceContext
private EntityManager em;

public List<StandardRods> getDefaultRodAndColor(String series, String style, String material, String color)
{
    Query getStandardRodsQuery = em.createNativeQuery("SELECT xxlt.xxlt_bpg_std_width_pkg.get_std_rods(:p_series_ind,:p_style_ind,:p_material_ind,:p_color_ind) FROM DUAL");
            getStandardRodsQuery.setParameter("p_series_ind", series)
            .setParameter("p_style_ind", style)
            .setParameter("p_material_ind", material)
            .setParameter("p_color_ind", color);
    List<StandardRods> standardRods = (List<StandardRods>) getStandardRodsQuery.getResultList();
    return standardRods;
}
}

我当前收到以下错误:

  

致电:SELECT   xxlt.xxlt_bpg_std_width_pkg.get_std_rods(:p_series_ind,:p_style_ind,:p_material_ind,:p_color_ind)   从双查询:DataReadQuery(sql =“ SELECT   xxlt.xxlt_bpg_std_width_pkg.get_std_rods(:p_series_ind,:p_style_ind,:p_material_ind,:p_color_ind)   FROM DUAL”)   org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:340)     在   org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:684)     在   org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:560)     在   org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2055)     在   org.eclipse.persistence.sessions.server.ServerSession.executeCall(ServerSession.java:570)     被截断了。请参阅日志文件以获取完整的stacktrace   原因:java.sql.SQLException:在索引:1处缺少IN或OUT参数

我已经对此进行了一段时间的调查,并且在没有使用其他工具的情况下,找不到任何关于处理存储函数的良好文档或示例的运气。任何反馈将不胜感激。

1 个答案:

答案 0 :(得分:0)

如果您要坚持使用JPA的@NamedNativeQuery,则需要一个JPA提供程序(例如Hibernate)。如果是Hibernate,则可以使用以下语法。

@NamedNativeQuery(
    name = "getStandardRods",
    query = "{ ? = call get_std_rods(?, ?, ?, ?) }",
    resultClass = StandardRods.class,
    hints = { @QueryHint( name = "org.hibernate.callable", value = "true") }
)
public class MyEntity {
    // ...
{

然后您可以按以下方式调用它。

@PersistenceContext
private EntityManager manager;

public List<StandardRods> getStandardRods(String series, String style, String material, String color) {

    return (List<StandardRods>) em.createNamedQuery("getStandardRods")
        .setParameter(1, series)
        .setParameter(2, style)
        .setParameter(3, material)
        .setParameter(4, color)
        .getResultList();
}

如果要避免使用JPA,可以使用普通的JDBC。

try (CallableStatement function = connection.prepareCall("{ ? = call get_std_rods(?, ?, ?, ?) }")) {
    function.registerOutParameter(1, Types.REF);
    function.setString(2, ...);
    function.setString(3, ...);
    function.setString(4, ...);
    function.setString(5, ...);
    function.execute();
    return (ResultSet) function.getObject(1);
}