5
votes

The "Session" interface has two methods that, in Scala due to type erasure, are reduced to having the same signature:

public ProcedureCall createStoredProcedureCall(String procedureName, Class... resultClasses)

public ProcedureCall createStoredProcedureCall(String procedureName, String... resultSetMappings)

Trying to implement them gives the error:

error: double definition: method createStoredProcedureCall:(procedureName: String, resultSetMappings: String*)org.hibernate.procedure.ProcedureCall and method createStoredProcedureCall:(procedureName: String, resultClasses: Class[_])org.hibernate.procedure.ProcedureCall at line 199 have same type after erasure: (procedureName: String, resultSetMappings: Seq)org.hibernate.procedure.ProcedureCall override def createStoredProcedureCall(procedureName: String, resultSetMappings: String): ProcedureCall = null ^

So how would I go about implementing this interface in a way that will both compile and work?

1
Ditch Hibernate and use SLICK? :)joescii
@barnesjd Perhaps in a future release. I have plenty to do without changing the technology stack of a production system.Donald.McLean
Also, Slick wasn't in production release when the project was started, so it could not have been considered.Donald.McLean
Oh, I see. Definitely a different story if it is a production system. :) I'm sorry you have to go through this, LOLjoescii
As I know there is no way you can implement both these methods in Scala for now. It is an interoperability problem with Java. Consider implementing the interface in Java and using it from Scalaserejja

1 Answers

1
votes

As serejja pointed out, you can write a shim in Java to do the translation for you:

Java:

package jibernate;

import org.hibernate.procedure.ProcedureCall;
import org.hibernate.SharedSessionContract;

public abstract class Yava implements SharedSessionContract {

  public ProcedureCall createStoredProcedureCallC(String n, Class... xs) {
    return createStoredProcedureCall(n, xs);
  }

  public ProcedureCall createStoredProcedureCallS(String n, String... xs) {
    return createStoredProcedureCall(n, xs);
  }

}

If you're using sbt, this can live in src/main/java/jibernate/Yava.java

Scala:

package whybernate

trait Mehssion extends jibernate.Yava {

  import org.hibernate.procedure.ProcedureCall

  def createStoredProcedureCall(n: String, h: Class[_], t: Class[_]*) =
    createStoredProcedureCallC(n, (h +: t):_*)

  def createStoredProcedureCall(n: String, h: String, t: String*) =
    createStoredProcedureCallS(n, (h +: t):_*)

}

You can call these functions in the same way, taking advantage of the fact that you're guaranteed to have at least one of the needed varargs.