sanaka
sanaka

Reputation: 37

Class cast exception in clojure

Getting clojure.core$count cannot be cast to java.lang.Number error for defined variable count

(defroutes jobs-routes
      (context "/jobs" []
        (POST "/jobValidation" [name status req]  (insert-job jobName jobStatus req)))

In this method I've define a variable count to store the value of total count from the query

(defn insert-job [jobName jobStatus req]
   (let [count (db/insert-job {:job-name name :status status})])
    (when (> count 0) (println (format "true" )))
    (insert-job req) ; 
)

Query: db/insert-job

-- :name insert-jobWithValidation :? :*
SELECT count(*)  FROM job_history WHERE job_name = :job-name and status = :status

Problem I want to check that whether If I'm getting out value greater than 0 so I can print something any if count is any positive value then I can perform something new

Upvotes: 0

Views: 153

Answers (2)

leetwinski
leetwinski

Reputation: 17859

that is probably because of your hugsql query header:

:? :* - returns the rowset, which is not a number. maybe :? :1 would be more suitable here. Anyway, the query doesn't return a count(*), it rather returns a hash-map (in case of :1) or a list of one hashmap (in case of :*), you would still need to retrieve the value from there.

Something like that (untested):

-- :name insert-jobWithValidation :? :1
SELECT count(*) as amount  FROM job_history WHERE job_name = :job-name and status = :status
(defn insert-job [name status req]
  (let [res (db/insert-job {:job-name name :status status})]
    (when (-> res :amount pos?) 
      (println true))
    (insert-job req)))

UPD: omg, let with no body, indeed, @Martin Půda, thanks )

i would say, what you want is something like that:

-- :name count-jobs-by-name-and-status :? :1
SELECT count(*) as amount  FROM job_history WHERE job_name = :job-name and status = :status
(defn insert-job-if-not-exists [name status req]
  (if (->> {:job-name name :status status}
           db/count-jobs-by-name-and-status
           :amount
           pos?)
    (println "job already exists")
    (insert-job req)))

Upvotes: 1

Martin Půda
Martin Půda

Reputation: 7568

Your let block has no body, you're closing it right after definitions vector:

(let [count (db/insert-job {:job-name name :status status})])

Note that you are shadowing core function count here.

So when you call this line: (when (> count 0) (println (format "true" ))), the value of count is count function:

count
=> #object[clojure.core$count 0x69c6a700 "clojure.core$count@69c6a700"]
(> count 0)
Execution error (ClassCastException)
class clojure.core$count cannot be cast to class java.lang.Number

There are some other errors and style inaccuracies:

  • the names of your variables don't match (jobName jobStatus vs name status)
  • you're calling (insert-job req) with only one argument, but this function has three
  • (> ... 0) is pos?
  • (format "true") is just "true"

Possible fix (maybe you will still have to modify it somehow):

(defn insert-job [job-name job-status req]
  (let [my-count (db/insert-job {:job-name job-name :status job-status})]
    (if (pos? my-count)
      (println "true")
      (insert-job job-name job-status req)))) 

Upvotes: 3

Related Questions