mapdb icon indicating copy to clipboard operation
mapdb copied to clipboard

Map DB is not working for me with kotlin.

Open karandaid opened this issue 6 years ago • 3 comments

Map DB is not working for me with kotlin. gradle

dependencies {
    compile(kotlin("stdlib-jdk8"))
    implementation(group="org.mapdb", name= "mapdb", version= "3.0.7")
    testCompile("junit", "junit", "4.12")
}

File.kt

import org.mapdb.DBMaker

fun main(array: Array<String>) {
    val db = DBMaker.memoryDB().make()
    val map = db.hashMap("map").createOrOpen()
    map.put("a", "a")
    db.close()
}

Error:(7, 13) Kotlin: Type mismatch: inferred type is String but Nothing? was expected. Projected type HTreeMap<out Any?, out Any?> restricts use of public open fun put(key: K?, value: V?): V? defined in org.mapdb.HTreeMap Error:(7, 18) Kotlin: Type mismatch: inferred type is String but Nothing? was expected. Projected type HTreeMap<out Any?, out Any?> restricts use of public open fun put(key: K?, value: V?): V? defined in org.mapdb.HTreeMap

karandaid avatar Jan 25 '19 16:01 karandaid

Hi guys, any updates on this? The same example works on Java but doesn't on Kotlin. I would like to use a nested data class as the map's value, as a use case. Version 3.0.8. Thanks

gabrielpaim avatar Apr 05 '20 01:04 gabrielpaim

Can you try again with kotlin 1.4.10?

IRus avatar Oct 09 '20 20:10 IRus

Cast to actual type will fix your issue:

import org.mapdb.DBMaker
import org.mapdb.HTreeMap

fun main() {
    val db = DBMaker.memoryDB().make()
    val map = db.hashMap("map").createOrOpen() as HTreeMap<String, String>
    map.put("a", "a")
    db.close()
}

Not sure is this way people use map db, like put literally Any to it, or have some specialization for every map.

Also, if it's repeated patter in your code base, some extension can be useful:

@Suppress("UNCHECKED_CAST")
fun <K, V> HTreeMap<*, *>.useAs(): HTreeMap<K, V> = this as HTreeMap<K, V>

This extension can be used this way:

import org.mapdb.DBMaker
import org.mapdb.HTreeMap

fun main() {
    val db = DBMaker.memoryDB().make()
    val map = db.hashMap("map").createOrOpen().useAs<String, String>()
    map.put("a", "a")
    db.close()
}

IRus avatar Oct 10 '20 08:10 IRus