我正在開發一個Java應用程序,最近一位同事告訴我,如果我爲我的一些需求使用存儲過程,我的解決方案將變得更整齊。我開始閱讀他們,他們看起來很有希望,但現在我很難讓Hibernate將從這種存儲過程返回的結果映射到java bean。將PostgreSQL的refcursor映射到使用Hibernate的java實體
這裏是我試圖去的過程:
CREATE OR REPLACE FUNCTION wrong_user_answers(testId INTEGER, userId INTEGER) RETURNS refcursor AS $wrong_user_answers$
DECLARE
ref refcursor;
BEGIN
OPEN ref FOR SELECT ua.*
FROM t_tests as t
JOIN t_user_answers as ua on ua.fk_test_id = t.pk_test_id
WHERE t.pk_test_id = testId and ua.fk_user_id = userId and is_correct(ua) = false;
RETURN ref;
END;
$wrong_user_answers$ LANGUAGE plpgsql;
這裏is_correct(ua)
是我定義的另一個存儲過程。我已經在PGAdmin中嘗試過這個過程,並且它完全返回我所期望的 - 包含用戶答案的refcursor。
這裏是我認爲應該得到這一切滾動代碼的Java的一部分:
附加註釋(@NamedNativeQuery
)在UserAnswerBean
:
@NamedNativeQueries({
@NamedNativeQuery(name = "getWrongUserAnswers",
query = "select wrong_user_answers(:testId, :userId)",
resultClass = UserAnswerBean.class)
})
@Entity
@Table(name = "t_user_answers")
public class UserAnswerBean {
和使用該程序的代碼:
Query query = getEntityManager().createNamedQuery("getWrongUserAnswers");
query.setParameter("testId", testId);
query.setParameter("userId", userId);
List<UserAnswerBean> answers = query.getResultList();
當接收到上下面erorr上述最後一行代碼執行的嘗試:
org.postgresql.util.PSQLException:列名pk_user_answer_id 並沒有到此ResultSet中。 org.postgresql.jdbc2.AbstractJdbc2ResultSet.findColumn(AbstractJdbc2ResultSet.java:2728) org.postgresql.jdbc2.AbstractJdbc2ResultSet.getInt(AbstractJdbc2ResultSet.java:2589) org.hibernate.type.descriptor.sql.IntegerTypeDescriptor $ 2.doExtract( IntegerTypeDescriptor.java:74) org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:64) org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:267) org.hibernate.type .AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:263) org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:253) org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:338) org.hibernate.loader.Loader.extractKeysFromResultSet(Loader.java:784) org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:720) org.hibernate.loader.Loader.processResultSet(Loader.java:952 )
我不知道如何在這裏繼續,我無法在互聯網上找到任何有用的資源。所以,我認爲這個問題是,我是返回REFCURSOR,選擇的不是立即的結果,所以我改變了存儲過程來:
CREATE OR REPLACE FUNCTION wrong_user_answers(testId INTEGER, userId INTEGER) RETURNS setof record AS $wrong_user_answers$
SELECT ua.*
FROM t_tests as t
JOIN t_user_answers as ua on ua.fk_test_id = t.pk_test_id
WHERE t.pk_test_id = testId and ua.fk_user_id = userId and is_correct(ua) = false;
$wrong_user_answers$ LANGUAGE sql;
遺憾這並沒有改變錯誤。
最後我瞭解的@NamedStoredProcedureQuery
註釋:
@NamedStoredProcedureQuery(name = "getWrongUserAnswers",
procedureName = "wrong_user_answers", parameters = {
@StoredProcedureParameter(name = "testId", type = Integer.class, mode = ParameterMode.IN),
@StoredProcedureParameter(name = "userId", type = Integer.class, mode = ParameterMode.IN) },
resultClasses = UserAnswerBean.class)
@Entity
@Table(name = "t_user_answers")
public class UserAnswerBean {
隨着改變java代碼:
Query query = getEntityManager().createNamedStoredProcedureQuery("getWrongUserAnswers");
query.setParameter("testId", testId);
query.setParameter("userId", userId);
List<UserAnswerBean> answers = query.getResultList();
這並沒有任何chnage錯誤!有人能幫我弄清楚我做錯了什麼嗎?
如果Hibernate在refcursors中表現良好,我可能會感到非常驚訝,除非你做了本地查詢'FETCH'語句,而不是期望它將它們理解爲結果集。 – 2014-12-27 16:27:31
看到我的第二次嘗試 - 沒有在那裏使用refcursor。順便說一句,我認爲我看到了一些地方,休眠消化refcursors沒有麻煩,可能玩智能和提取他們 – 2014-12-27 16:50:47
它實際上是PgJDBC特殊情況下refcursor在某些情況下,通過正常的jdbc APIs將其視爲多個結果集。 – 2014-12-27 18:06:52