我的目标是使用@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参数
我已经对此进行了一段时间的调查,并且在没有使用其他工具的情况下,找不到任何关于处理存储函数的良好文档或示例的运气。任何反馈将不胜感激。
答案 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);
}