Datomic Cloud中:db.type/uri返回URIImpl而非java.net.URI的问题咨询
Datomic Cloud: 查询返回
com.cognitect.transit.impl.URIImpl而非java.net.URI导致方法调用失败 问题现象
向Datomic Cloud存入java.net.URI类型的数据(对应schema中:db.type/uri类型的属性)后,查询返回的对象类型为com.cognitect.transit.impl.URIImpl,而非预期的java.net.URI。直接调用getHost等java.net.URI的方法时,会抛出如下异常:
Unhandled java.lang.IllegalArgumentException No matching field found: getHost for class com.cognitect.transit.impl.URIImpl
该问题仅出现在Datomic Cloud环境,本地开发环境无此问题,且经Datomic支持人员Jaret Binford确认,此为Datomic官方bug。
重现代码
(require '[datomic.client.api :as d]) (def schema [{:db/ident :test/url :db/valueType :db.type/uri :db/unique :db.unique/identity :db/cardinality :db.cardinality/one :db/doc "The URL."}]) ; 修正原代码语法错误 (def cfg {:server-type :cloud :region "" :system "" :endpoint ""}) (def client (d/client cfg)) (d/create-database client {:db-name "test"}) (def conn (d/connect client {:db-name "test"})) (d/transact conn {:tx-data schema}) (d/transact conn {:tx-data [{:test/url (java.net.URI. "https://www.google.com")}]}) ;; 查询返回URIImpl实例 (let [q '[:find ?url :where [?e :test/url ?url]] db (d/db conn)] (d/q q db)) ;; => [[#object[com.cognitect.transit.impl.URIImpl 0x938b85 "https://www.google.com"]]] ;; 验证返回类型 (let [q '[:find ?url :where [?e :test/url ?url]] db (d/db conn)] (type (ffirst (d/q q db)))) ;; => com.cognitect.transit.impl.URIImpl ;; 调用方法抛出异常 (let [q '[:find ?url :where [?e :test/url ?url]] db (d/db conn)] (.getHost (ffirst (d/q q db)))) ;; => Unhandled java.lang.IllegalArgumentException ;; No matching field found: getHost for class com.cognitect.transit.impl.URIImpl
临时解决方案
在官方修复前,可将返回的URIImpl实例转换为java.net.URI后再调用方法:
(defn transit-uri->java-uri [transit-uri] (java.net.URI. (str transit-uri))) ;; 使用示例 (let [q '[:find ?url :where [?e :test/url ?url]] db (d/db conn) uri (transit-uri->java-uri (ffirst (d/q q db)))] (.getHost uri)) ;; => "www.google.com"
内容的提问来源于stack exchange,提问作者adham327
相关产品推荐
相关产品推荐

