Skip to content

Instantly share code, notes, and snippets.

@domdorn
Last active August 29, 2015 14:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save domdorn/fb504a510ffda470991b to your computer and use it in GitHub Desktop.
Save domdorn/fb504a510ffda470991b to your computer and use it in GitHub Desktop.
Problem with jOOQ and Scala
package helpers;
import org.jooq.DSLContext;
import java.util.Collection;
/**
*
*/
public class DSLWrapper {
private final DSLContext context;
public DSLWrapper(final DSLContext context) {
this.context = context;
}
public int execute(String sql, Collection<? extends Object> arguments) {
return context.execute(sql, arguments.toArray());
}
}
[info] Compiling 1 Scala source and 1 Java source to /home/domdorn/lyrix/lyrix_php/playlyrix/target/scala-2.11/classes...
[error] /home/domdorn/lyrix/lyrix_php/playlyrix/app/controllers/Security.scala:54: overloaded method value execute with alternatives:
[error] (x$1: String,x$2: org.jooq.QueryPart*)Int <and>
[error] (x$1: String,x$2: Object*)Int
[error] cannot be applied to (String, Long, String)
[error] e.execute(sql, userId, uuid)
[error] ^
[error] one error found
[error] (compile:compile) Compilation failed
val userId = 1L
val uuid = UUID.randomUUID().toString.replace("-", "")
val sql = "INSERT INTO sometable (userId, hash) VALUES (?, ?);"
DB.withTransaction(conn => {
val e = DSL.using(conn, SQLDialect.POSTGRES)
e.execute(sql, userId, uuid) // does not work
// e.execute(sql, List(userId, uuid) : _*) // does not work either
})
val e = DSL.using(conn, SQLDialect.POSTGRES)
val l : java.util.ArrayList[Object] = new java.util.ArrayList[Object]()
l.add(java.lang.Long.valueOf(userId))
l.add(uuid)
new DSLWrapper(e).execute(sql, l)
@lukaseder
Copy link

@ktoso: Thanks for opening that issue.
@lrytz: Interesting. I guess the g(Object...) case is really sign for a compiler bug. I wonder how type inference with generic methods plays into this kind of interoperability, i.e. when the signature is something like:

  public <T> void h(T... o) {
    System.out.println("t...");
  }

On a bytecode level, T... is really erased again to Object[], but on a language level, there is a lot of (false) type-safety and type-inference that is applied. I'm saying false, because any list of parameters will be viable, in principle.

This becomes particularly interesting when the T type has side-effects on the call site, such as:

  public <T> T h(T... o) {
    System.out.println("t...");
    return o != null && o.length > 0 ? o[0] : null;
  }

I wonder if this would produce the same behaviour in Scala as in Java, e.g. (pseudo-repl):

scala> 1 == t.h(1)
true

@lukaseder
Copy link

I've also copied my comment over to SI-8800

@lrytz
Copy link

lrytz commented Aug 19, 2014

@lukaseder: Yes, that works:

scala> t.h(1) == 1
t...
res1: Boolean = true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment