我正在开发Java应用程序,最近一位同事告诉我,如果我使用存储过程来满足某些需求,我的解决方案将变得更加整洁。我开始阅读有关它们的文章,它们看起来确实很有希望,但是现在我很难使Hibernate将存储过程返回的结果映射到Java bean。
这是我要尝试的步骤:
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:在此ResultSet中找不到列名pk_user_answer_id。org.postgresql.jdbc2.AbstractJdbc2ResultSet.findColumn(AbstractJdbc2ResultSet.java:2728)org.postgresql.jdbc2.AbstractJdbc2ResultSet.getInt(AbstractJdbc2ResultSet.java:2589)org.hibernate.type.descriptor.sql.IntegerTypeDescriptor $ :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。
我不知道该如何进行,我在互联网上找不到任何有用的资源。因此,我认为问题在于我正在返回refcursor,而不是立即返回select的结果,因此我将存储过程更改为:
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();
这也没有改变错误!有人可以帮我弄清楚我在做什么错吗?
终于我能够解决我的问题了。
我想我可能在第二种方法上报告了错误的错误。我在使用反射器的斗争中基本上没有运气,但是使用LANGUAGE sql给了我想要的东西。那是存储过程:
CREATE OR REPLACE FUNCTION wrong_user_answers(testId INTEGER, userId INTEGER)
RETURNS setof t_user_answers
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;
与之前的唯一区别是,我已明确指定返回类型为setof t_user_answers
。批注和Java代码与问题中的粘贴完全相同,现在一切对我都有效。
PS:对于那些想知道我不得不更加努力次获得当我有结果是没有-DB实体一切顺利,但最后我发现@SqlResultSetMapping批注与@ConstructorResult classes
subannotation解决问题(很难找到解决方案虽然)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句