java - How do I fix "ambiguous overload" when using Hibernate with Scala? - Stack Overflow

admin2025-05-01  0

I have begun writing a webserver using Scala+Akka, combining it with Hibernate+MySQL for data storage. Despite spending several days translating Java+Hibernate tutorials over to Scala, I got something working.

Currently, I can successfully:

Get an entity by it's ID field specifically, using:

session.get(classOf[T], id)

Get a list of entries using:

  val builder: CriteriaBuilder = sessionFactory.getCriteriaBuilder
  val query: CriteriaQuery[T] = builder.createQuery(classOf[T])
  val root: Root[T] = query.from(classOf[T])
  val all: CriteriaQuery[T] = query.select(root)

  val allQuery: TypedQuery[T] = session.createQuery(all)
  ... (convert results to Seq[T]

Next, I wanted to implement getting a list of entries with a specific column value. From what I read online, it should be the following:

  val cb = sessionFactory.getCriteriaBuilder
  val query = cb.createQuery(classOf[T])
  val root = query.from(classOf[T])
  
  val queryResults: TypedQuery[T] = 
    session.createQuery(query.select(root).where(root.get("status").equalTo(status)))

The problem here is that it seems query.where result is both a Predicate* and a Expression[Boolean], which causes this error:

I managed to put this error off for querying by ID by using the session.get function, but it seems I will need to fix this to query by specific fields, unless there is an alternative approach to querying?

Any suggestions?

I have begun writing a webserver using Scala+Akka, combining it with Hibernate+MySQL for data storage. Despite spending several days translating Java+Hibernate tutorials over to Scala, I got something working.

Currently, I can successfully:

Get an entity by it's ID field specifically, using:

session.get(classOf[T], id)

Get a list of entries using:

  val builder: CriteriaBuilder = sessionFactory.getCriteriaBuilder
  val query: CriteriaQuery[T] = builder.createQuery(classOf[T])
  val root: Root[T] = query.from(classOf[T])
  val all: CriteriaQuery[T] = query.select(root)

  val allQuery: TypedQuery[T] = session.createQuery(all)
  ... (convert results to Seq[T]

Next, I wanted to implement getting a list of entries with a specific column value. From what I read online, it should be the following:

  val cb = sessionFactory.getCriteriaBuilder
  val query = cb.createQuery(classOf[T])
  val root = query.from(classOf[T])
  
  val queryResults: TypedQuery[T] = 
    session.createQuery(query.select(root).where(root.get("status").equalTo(status)))

The problem here is that it seems query.where result is both a Predicate* and a Expression[Boolean], which causes this error:

I managed to put this error off for querying by ID by using the session.get function, but it seems I will need to fix this to query by specific fields, unless there is an alternative approach to querying?

Any suggestions?

Share Improve this question edited Jan 2 at 18:13 Kris Rice asked Jan 2 at 18:03 Kris RiceKris Rice 8791 gold badge11 silver badges29 bronze badges 3
  • The error is with the two variants of where, not with the select. – Gaël J Commented Jan 2 at 18:10
  • Does it work if you explicitly cast the content of the where to one of the two types? Using .asInstanceOf for instance. Feels a bit weird to have to do that but I don't see why it would be different in Scala. I guess same issue would arise in Java. – Gaël J Commented Jan 2 at 18:13
  • @GaëlJ Looking further, I believe its because the Predicate I am using is also an Expression[Boolean], so it doesn't know which function to use for where. I tried asInstanceOf, no luck. I also tried explicitly typing the expression to a separate variable and passing it, no luck. My last attempt was creating an Array[Predicate] and passing it, still no luck – Kris Rice Commented Jan 2 at 18:17
Add a comment  | 

1 Answer 1

Reset to default 0

Ok so the issue is with the fact that the Predicate returned by equalsTo is also of type Expression[Boolean], so the exact function to call is ambiguous.

I fixed the issue with another Scala -> Java hack...

  val cb = sessionFactory.getCriteriaBuilder
  val query = cb.createQuery(classOf[T])
  val root = query.from(classOf[T])

  val expression: Predicate = root.get("status").equalTo(status) // <= Create predicate
  val predicates: Array[Predicate] = Array(expression)                                       // <= Store predicate in Scala Array

  // Call where, getting the Java array from the Scala Array
  val all = query.select(root).where(predicates:_*)                                          

  val queryResults: TypedQuery[T] = session.createQuery(all)

By passing the Java array of the Predicates, it is then not ambiguous and the function where(Predicate... predicates) is called.

转载请注明原文地址:http://anycun.com/QandA/1746103756a91718.html