PostgreSQL函数上的Hibernate executeUpdate()

时间:2013-08-08 18:02:29

标签: java hibernate postgresql

我正在使用带有PostgreSQL中的函数的hibernate来更新数据库中的记录。

以下是PostgreSQL函数,

    CREATE OR REPLACE FUNCTION updatesegment(segid bigint, segname text, segdesc text, segmeta text)
      RETURNS void AS
    $BODY$
      BEGIN
        UPDATE segment
        SET
           name = segname,
           description = segdesc,
           segmentmetadata = segmeta
        WHERE
           id = segid;
      END;
    $BODY$
    LANGUAGE plpgsql;

在java代码中,我调用了如下函数。

public int updateSegment(Long segmentId, String segName, String segDesc, String segMeta) {

    SQLQuery query = (SQLQuery)sessionFactory.getCurrentSession().createSQLQuery("SELECT updatesegment(:segmentId, :segName, :segDesc, :segMeta)")
            .setParameter("segmentId", segmentId)
            .setParameter("segName", segName)
            .setParameter("segDesc", segDesc)
            .setParameter("segMeta", segMeta);

    int rows = query.executeUpdate();

    return rows;
}

当我使用正确的输入参数调用上面的updateSegment()java函数时,DB中的记录会按预期更新。但是query.executeUpdate()总是返回0,因为它应该返回1。

我做错了什么,为什么executeUpdate()不返回1?

提前致谢... !!!

3 个答案:

答案 0 :(得分:1)

所以你要调用executeUpdate(),但是传递一个SELECT查询?即使SELECT查询要调用更新行的函数,函数也会更新行,而不是SELECT语句。因此,executeUpdate 1)不会知道要查找更新的行(它是一个SELECT,为什么会更新行?),2)即使知道尝试也无法获取计数。

尝试直接在控制台中运行SELECT语句,看看它是否告诉你它更新了1行......如果这没有告诉你有关行的更新,Hibernate将如何知道?

正如@ dic19所说,如果你想要获得该值,让你的函数返回该值,使用list()而不是executeUpdate()然后拉出该值从结果List

答案 1 :(得分:1)

为了在您的函数中获得受影响的行,您需要进行一些更改:

CREATE OR REPLACE FUNCTION updatesegment(segid bigint, segname text, segdesc text, segmeta text)
  RETURNS integer AS
$BODY$
  DECLARE
    rowsAffected integer := 0;
  BEGIN
    UPDATE segment
    SET
       name = segname,
       description = segdesc,
       segmentmetadata = segmeta
    WHERE
       id = segid;
    GET DIAGNOSTICS rowsAffected = ROW_COUNT; --here you get the affected rows
  END;
$BODY$
LANGUAGE plpgsql;

然后你也应该相应地修改你的java代码,以执行调用你的函数的SELECT查询并检索它将返回的整数。

来源: PostreSQL Documentation

答案 2 :(得分:1)

在PL / PgSQL函数中执行的SQL不会影响rowcount。

如果确实如此,你会如何期望从两个表中删除DELETE的函数然后更新第三个函数?它会返回所有三个行数的总和吗?最后一次操作的行数?什么?

如果您DELETE表中有一条记录而另一条记录INSERT,那该怎么办? rowcount是零,一个还是两个?一切都有意义。

如果要使用查询行计数,请不要将查询包装在PL / PgSQL函数中。

如果必须将它们包装在函数中,则需要将行计数提取到GET DIAGNOSTICS的变量中并返回,例如:

CREATE OR REPLACE FUNCTION updatesegment(segid bigint, segname text, segdesc text, segmeta text, OUT nrows integer)
  RETURNS integer AS
$BODY$
  BEGIN
    UPDATE segment
    SET
       name = segname,
       description = segdesc,
       segmentmetadata = segmeta
    WHERE
       id = segid;
    -- store the row count in the nrows OUT parameter
    GET DIAGNOSTICS nrows = ROW_COUNT;
  END;
$BODY$
LANGUAGE plpgsql;

JDBC不知道这是一个rowcount,它只是一个函数返回值。因此,您必须将其与execute而不是executeUpdate一起使用,然后获取结果行以确定受影响的行数。这有点可怕;除非你需要SECURITY DEFINER,否则我很难想象你为什么要通过一个函数来做这件事。

目前无法设置函数的rowcount结果。