I'm new to Scala, and I can't figure out how to solve a compiling error for method withTransaction :
Cannot resolve overloaded method 'withTransaction'
object Global {
def goBootstrap(app: Application) {
Logger.info(" **** start *****")
onGet();
}
def onGet() {
import play.db.jpa.JPA
Logger.info("Cnnection start");
JPA.withTransaction(JPA.em =>
{
val resultsList = JPA.em.createNamedQuery("findCity").setParameter("name", "Boston").getResultList
}
);
}
}
This code snippet is located in a Global.scala file in Play project (version 2.3.X). JPA came from import play.db.jpa.JPA
How can I solve this compiling error?
The error is telling you that there is no method on JPA whose signature matches the parameters you're passing. You are calling JPA.withTransaction( () => Unit).
Looking at the source there are three methods withTransaction with Unit return types:
void withTransaction(Consumer<EntityManager> block);
void withTransaction(String name, Consumer<EntityManager> block);
void withTransaction(String name, boolean readOnly, Consumer<EntityManager> block);
I'm going to assume that you're trying to use the first of those methods. Looking at the docs for Consumer it requires a single argument.
In short, you need to provide an input to your block, something like:
JPA.withTransaction(JPA.em => {
val resultsList = JPA.em.createNamedQuery("findCity").setParameter("name", name).getResultList
});
The problem is that you can't directly instantiate a JPA connection through scala. Also because the play 2.3 framework does not support this feature: https://www.playframework.com/documentation/2.3.x/ScalaHome
Related
I have a problem that has been challenging me for a few days with no resolution (more directly, no resolution I feel is correct). The issue is around callbacks, Java implementation vs Kotlin implementation
I have this Java method:
public void setOnSelectionChange(MapControlUpdate mapMenuControl) {
this.mapControlUpdate = mapMenuControl;
}
private MapControlUpdate mapControlUpdate;
public interface MapControlUpdate {
void onSelectionChange(MAP_TYPE mapType);
}
Using the above implementation I have what I want (below) in both Java and Kotlin.
Java (before):
widgetMapType.setOnSelectionChange(mapType -> {
Toast.makeText(getContext(), "clicked: " + mapType, Toast.LENGTH_LONG).show();
});
Kotlin (before):
widgetMapType.setOnSelectionChange {
Toast.makeText(context, "clicked: $it", Toast.LENGTH_LONG).show()
}
The new Kotlin code, after conversion is:
fun setOnSelectionChange(mapMenuControl: MapControlUpdate?) {
mapControlUpdate = mapMenuControl
}
private var mapControlUpdate: MapControlUpdate? = null
After the conversion to Kotlin the Java usage remains unchanged but I need to change the Kotlin code as follows or I get a syntax error:
Kotlin (after):
widgetMapType.setMapMenuControl(object: WidgetMapType.MapControlUpdate {
override fun onSelectionChange(mapType: WidgetMapType.MAP_TYPE?) {
Toast.makeText(context, "clicked: $mapType", Toast.LENGTH_LONG).show()
}
})
In order to get back to where I'd like to be I found that the only solution appear to be to implement 2 callbacks; 1 to allow Java to work with the original syntax and another to allow Kotlin syntax to remain the same.
This is the code I'm using (it works):
var onSelectionChange: MapControlUpdate? = null
private var onSelectionChangeListener: ((MapDisplayTypes?) -> Unit)? = null
fun setOnSelectionChange(listener: (MapDisplayTypes?) -> Unit){
onSelectionChangeListener = listener
}
and I fire both callbacks as appropriate
onSelectionChange?.onSelectionChange(it) // Java
onSelectionChangeListener?.invoke(it) // Kotlin
I really cannot believe that there isn't a more correct method but my searches (here and on the web) have returns tons of examples for Kotlin and Java but they all align with my above examples based on the code (also shown above). I suspect there maybe an annotation or something that I'm missing so finding no other solution I'm turning to the community here.
Thank you ahead of time!!
I suspect that you will need to keep just your interface MapControlUpdate definition in Java.
Instead of two callbacks you would keep just one callback and convert as appropriate:
var onSelectionChange: MapControlUpdate? = null
fun setOnSelectionChange(listener: (WidgetMapType.MAP_TYPE?) -> Unit){
onSelectionChangeListener = object : MapControlUpdate {
override fun onSelectionChange(mapType: WidgetMapType.MAP_TYPE?) {
listener(mapType)
}
}
}
Or write a helper function if MapControlUpdate is used more than once.
But the real solution is, as karmakaze says: keep the interface in Java until Kotlin 1.4 and then declare it as fun interface.
Due to project requirement we need to import the project mappings & other objects from a different server. But we found that all the mapping context becomes undefined.
I am trying to write a groovy program to set the context at a bulk. I have written the below code but somehow the interfaceList is empty and thus unable to perform odiInterface.setOptimizationContext(context);.
Below is my code. For brevity I haven't mentioned the packages stmt.
def all the variables like url,driver,schema etc
def all variables like MasterInfo, auth, transaction, etc
def OdiContext context = ((IOdiContextFinder) odiInstance.getTransactionalEntityManager().getFinder(OdiContext.class)).findByCode("CTX_ANN1_S4")
for (p in odiProjectList) {
if (p.getName() == "PrjDemo_TA") {
def OdiFolderList = p.getFolders()
for (f in OdiFolderList) {
if (f.getName() == "TrgDemoMod_Comn_TA_S4") {
// def OdiInterfaceList2 = f.getInterfaces()
// def OdiMappingList = odiInstance.getTransactionalEntityManager().findAll( Mapping.class)
def OdiInterfaceList = ((IOdiInterfaceFinder) odiInstance.getTransactionalEntityManager().getFinder(OdiInterface.class)).findByProject(projectCode, folderName)
for (m in OdiInterfaceList2) {
println(m.getName() + "|" + m.getClass()) //+ "|" + m.getParent() + "|" + m.getFolder() )
m.setOptimizationContext(context)
}
tm.commit(txnStatus)
}
}
}
}
The line which initializes OdiInterfaceList is not throwing any error nor populating desired interface lists of all the interfaces within a folder.
So m.setOptimizationContext(context) is not executed.
If i substitute that line with:
def OdiMappingList = odiInstance.getTransactionalEntityManager().findAll( Mapping.class)
within a for ... loop i can able to access the mappings but I don't know how to set its context OdiMappingList as setOptimizationContext is an interface's method.
I'm unable to reproduce your case as I don't have the environment to test it, but I still think I can help.
First, I refactored your code so its more groovy:
def OdiContext context = ((IOdiContextFinder) odiInstance.getTransactionalEntityManager().getFinder(OdiContext.class)).findByCode("CTX_ANN1_S4")
// Looking for the project
def prjDemo = odiProjectList.find { it.name == "PrjDemo_TA" }
assert prjDemo : "Unable to find ODI project"
//Getting the Mappings
def mappingList = odiInstance.getTransactionalEntityManager().findAll( Mapping.class)
assert ! mappingList.toList().empty : "Mappings not found"
// Printing interfaces
mappingList.each {
it.setDefaultContext(context as IContext)
}
With those asserts, you may be able to know more in detail where your code may be really failing.
I noticed that IOdiInterfaceFinder is marked as deprecated, so it might not play well with Oracle 12c. Check your versions.
Probably it would be better if you try to replace that deprecated code with a more updated version. I found some similar code to yours in this page, so it might be useful.
UPDATE:
Updated the code to use Mapping class. As it has setDefaultContext(IContext ctx) method and OdiContext implements IContext, maybe it might work.
Scenario is an interface of Cucumeber.api package.
I want to use this interface to get scenario name.
I am trying:
String string = () - > {
public String getName(Scenario scenario) {
return scenario.getName().toString();
}
});
but it is giving error, what am I missing here?
I am already following several posts (like below), but didn't what wrong I am doing:
Lambda Expression is not working, getting terminated
I just started Kotlin so please be nice :)
I have a class that is responsible for fetching some data and notify the main activity that its need to update its UI.
So i have made a function in my DataProvider.kt :
fun getPeople(fromNetwork: Boolean, results: ((persons: Array<Person>, error: MyError?) -> Unit)) {
// do some stuff stuff
val map = hashMapOf(
"John" to "Doe",
"Jane" to "Smith"
)
var p = Person(map)
val persons: Array <Person> = arrayOf (p)
results(persons, null)
}
So i want to call this from my activity but i can't find the right syntax ! :
DataProvider.getPeople(
true,
results =
)
I have try many things but i just want to get my array of persons and my optional error so i can update the UI.
The goal is to perform async code in my data provider so my activity can wait for it.
Any ideas ? Thank you very much for any help.
This really depends on how you define the callback method. If you use a standalone function, use the :: operator. First (of course), I should explain the syntax:
(//these parenthesis are technically not necessary
(persons: Array<Person>, error: MyError?)//defines input arguments: an Array of Person and a nullable MyError
-> Unit//defines the return type: Unit is the equivalent of void in Java (meaning no return type)
)
So the method is defined as:
fun callback(persons: Array<CustomObject>, error: Exception?){
//Do whatever
}
And you call it like:
DataProvider.getPeople(
true,
results = this::callback
)
However, if you use anonymous callback functions, it's slightly different. This uses lambda as well:
getPeople(true, results={/*bracket defines a function. `persons, error` are the input arguments*/persons, error -> {
//do whatever
}})
Yes Kotlin has a great way of using callback functions which I will show you an example of how I use them below:
fun addMessageToDatabase(message: String, fromId: String, toId: String,
addedMessageSuccessHandler: () -> Unit,
addedMessageFailureHandler: () -> Unit) {
val latestMessageRef = mDatabase.getReference("/latest-messages/$fromId/$toId")
latestMessageRef.setValue(message).addOnSuccessListener {
latestMessageUpdateSuccessHandler.invoke()
}.addOnFailureListener {
latestMessageUpdateFailureHandler.invoke()
}
}
And finally you can utilise the new callbacks with the following code
databaseManager.updateLatestMessageForUsers(message, fromId, toId,
latestMessageUpdateSuccessHandler = {
// your success action
},
latestMessageUpdateFailureHandler = {
// your failure action
})
So basically when I successfully add a new row to my database I'm invoking a success or a failure response to the caller of the service. Hopefully this will help out someone.
How might a Java program wrap a value into a scala.Either? For example, how would the following Scala code be written in Java?
Right("asdf")
Left(new Exception())
The following fails with "cannot find symbol method apply(java.lang.String)"
Right.apply("asdf");
The following fails with "cannot find symbol method apply(java.lang.Exception)"
Left.apply(new Exception());
If I understand the question correctly, assume you have the following Scala method:
def foo(stringOrDate: Either[String, Date]) {
//...
}
you can call it from Java code by single creating Either subclasses instances:
scalaObject.foo(new Left<String, Date>("abc"));
scalaObject.foo(new Right<String, Date>(new Date()));
If you want to pass functions from Java code, you have to implement Function* trait depending on the function arity:
def foo(stringOrStringFun: Either[String, () => String]) {
//...
}
In Java:
scalaObject.foo(new Left<String, scala.Function0<String>>("abc"));
scalaObject.foo(new Right<String, scala.Function0<String>>(
new scala.Function0<String>() {
#Override
public String apply() {
throw new RuntimeException();
}
}));
Of course in Scala it is much simpler as it supports lambdas on the syntax level:
foo(Left("abc"))
foo(Right(throw new RuntimeException()))