【问题标题】:Clojure JDBC - This ResultSet is closedClojure JDBC - 此 ResultSet 已关闭
【发布时间】:2019-04-05 18:05:35
【问题描述】:

我目前正在学习使用 Clojure 和与 postgresql 的连接,但我被卡住了。在我的代码中,我可以使用java.jdbc 依赖项成功查询使用SELECT,但是当我UPDATEINSERT 时出现异常

我正在使用这些依赖项

[org.clojure/java.jdbc "0.7.8"]
[postgresql "9.3-1102.jdbc41"]

这是我的 SELECT-ing 工作代码,来自名为 public."user" 的表

(ns knp-api.model.user
  (:require [clojure.java.jdbc :as sql]))


(def db "jdbc:postgresql://ampersanda@localhost:5432/idjoesoft_klinik")

(defn get-count [q]
  "Get count key from query
   It takes jdbc.query as parameter"
  (:count (first (into [] q))))

(defn is-user-email-available? [e]
  "Returns boolean when email is available.
   Take one parameter, it's email"
  (let [q "SELECT COUNT(*) FROM public.\"user\" t WHERE user_email = ?"]
    (sql/query db [q e] {:result-set-fn #(= 1 (get-count %))})))

这不是我的代码导致出现异常

(defn set-user-timestamp-and-token [email token timestamp]
  "update user current token and last login time inside database.
   Takes email, token, and current timestamp as parameter"
  (sql/update! db 
               "public.\"user\"" 
               {:user_last_login (str "to_timestamp(" timestamp ")") 
                :user_token token}  
               ["user_email = ?" email]))

这是个例外

更新

我也尝试使用 REPL 创建表,我也得到了相同的结果。

knp-api.handler=> (require '[clojure.java.jdbc :as sql])
nil
knp-api.handler=> (sql/db-do-commands "jdbc:postgresql://ampersanda@localhost:5432/idjoesoft_klinik" (sql/create-table-ddl :testing [[:data :text]]))

PSQLException This ResultSet is closed.  org.postgresql.jdbc2.AbstractJdbc2ResultSet.checkClosed (AbstractJdbc2ResultSet.java:2852)

【问题讨论】:

  • 如果结果集在关闭后使用,则会发生错误。例如,如果在自动提交模式下执行多个交错语句,就会发生这种情况。您还使用了相当旧版本的 PostgreSQL JDBC 驱动程序。
  • 感谢您的回复。对 PostgreSQL JDBC 驱动程序有什么建议吗?我按照 Heroku 的这些步骤进行操作。
  • @MochamadLuckyPradana : 运气好吗?
  • @Ashwin:不幸的是,没有:(,我改用funcool/clojure.jdbc

标签: postgresql jdbc clojure


【解决方案1】:

我怀疑更新进行得很好,然后它试图返回已更改的行,并试图以惰性序列的形式返回。尝试打印/处理延迟结果序列的东西可能在连接关闭后这样做。

尝试将 select 语句包装在对 doall 的调用中,以确保立即读取它并且不允许成为惰性数据库。

【讨论】:

  • 所以,我尝试在我的is-user-email-available? 函数内部使用doall 包装我的SELECT 查询,但是我得到了一个不同的错误,即Don't know how to create ISeq from: java.lang.Boolean。这个函数应该返回布尔值,所以我将代码更改为(let [q "SELECT COUNT(*) FROM public.\"user\" t WHERE user_email = ?"] (= 1 (first (doall (map :count (sql/query db [q e])))))),它成功返回布尔值,但是当我执行update查询时,它仍然是关于ResultSet为空的相同错误
  • 感谢您的检查,这是一个常见错误,我将把它留给其他有类似情况的人,尽管它似乎不是您问题的答案。如果你在几天内没有得到正确的答案,我会悬赏这个问题以尝试获得更多关注。
  • 我会继续努力寻找答案,如果我发现了什么我会更新。谢谢你帮助我。
【解决方案2】:

今天遇到同样的问题,根本原因是 postgresql java 驱动程序。 postgresql "9.3-1102.jdbc41" 已有 5 年历史,升级到 42.2.6 后问题消失了。

【讨论】:

  • 我还没试过但是谢谢你的回答
【解决方案3】:

我记得遇到过这个问题,但这是很多年前的事了,我不记得解决方案了。但是,在 Clojure 中包装原始 JDBC 并不是一个好主意。有许多优秀的 Clojure 库使使用数据库变得更加容易。我特别推荐SQL KormaHug SQL

【讨论】:

  • 远离科尔马!这是越野车和无人维护。自己看项目的github问题
【解决方案4】:

花了一段时间试图解决这个问题我可以确认在我的情况下更新 postgresql java 驱动程序解决了这个问题,如果有人遇到同样的问题尝试使用来自 clojars/maven 的最新驱动程序,Clojars 甚至有一条消息告诉你应该使用 maven central 的版本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-16
    • 2018-09-17
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 2020-03-31
    • 1970-01-01
    相关资源
    最近更新 更多