I have a Scala class that is trying to implement a Java interface (EntityManager in JavaEE 7 for unit testing purposes to be specific). The interface has these two methods (among others):
public StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses);
public StoredProcedureQuery createStoredProcedureQuery(String procedureName, String... resultSetMappings);
In the Scala implementation I have:
override def createStoredProcedureQuery(procedureName: String, resultClasses: Class[_]*): StoredProcedureQuery = ???
override def createStoredProcedureQuery(procedureName: String, resultSetMappings: String*): StoredProcedureQuery = ???
However, I get the following error:
MyTest.scala:134: error: double definition:
method createStoredProcedureQuery:(procedureName: String, resultSetMappings: String*)javax.persistence.StoredProcedureQuery and
method createStoredProcedureQuery:(procedureName: String, resultClasses: Class[_]*)javax.persistence.StoredProcedureQuery at line 133
have same type after erasure: (procedureName: String, resultSetMappings: Seq)javax.persistence.StoredProcedureQuery
override def createStoredProcedureQuery(procedureName: String, resultSetMappings: String*): StoredProcedureQuery = ???
I have not been able to come up with a work around. My Google searches also failed to find and answer. I'm using Scala 2.10.4.
AFAIK the EntityManager
Java interface cannot be implemented directly in Scala. The Java varargs are converted to Seq[Class[_]]
in the first method and Seq[String]
in the second method. Because of erasure, both methods then appear as having the same signature createStoredProcedureQuery(String, Seq[_])
.
I can only propose a workaround for this issue. You should write a Java abstract class that extends the EntityManager
interface and implement the 2 offending methods by delegating to 2 other abstract methods with different names in order to disambiguate:
public abstract class EntityManagerWorkaround implements EntityManager {
@Override
public StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses) {
return createStoredProcedureQueryForResultClasses(procedureName, resultClasses);
}
@Override
public StoredProcedureQuery createStoredProcedureQuery(String procedureName, String... resultSetMappings) {
return createStoredProcedureQueryForResultSetMappings(procedureName, resultSetMappings);
}
public abstract StoredProcedureQuery createStoredProcedureQueryForResultClasses(String procedureName, Class... resultClasses);
public abstract StoredProcedureQuery createStoredProcedureQueryForResultSetMappings(String procedureName, String... resultSetMappings);
}
Now you can extend the abstract class from Scala and implement the disambiguated methods:
class EntityManagerImpl extends EntityManagerWorkaround {
override def createStoredProcedureQueryForResultClasses(procedureName: String, resultClasses: Class[_]*) = ???
override def createStoredProcedureQueryForResultSetMappings(procedureName: String, resultSetMappings: String*) = ???
}