Scala API

OrientDB is a NoSQL database writen in Java, we can use it in scala easily. Look also at Scala utilities and tests project for Scala high level classes built on top of OrientDB.

using SBT

Use the following configuration:

  1. fork := true

Java method invocation problems

Usually the main problems are related to calling conventions between Scala and Java.

Parameters

Be careful to pass parameters to methods with varargs like db.query(...). You need to convert it to java’s repeated args correctly.

Look at these links:

http://stackoverflow.com/questions/3022865/calling-java-vararg-method-from-scala-with-primitives

http://stackoverflow.com/questions/1008783/using-varargs-from-scala

http://stackoverflow.com/questions/3856536/how-to-pass-a-string-scala-vararg-to-a-java-method-using-scala-2-8

Collections

You can only use java collections when define pojos. If you use scala collections, they can be persisted, but can’t be queried.

This’s not a problem, if you imported:

  1. import scala.collection.JavaConverters._
  2. import scala.collection.JavaConversions._

You don’t need to convert Java and Scala collections manually (even don’t need to invoke .asJava or .asScala) You can treat these java collections as scala’s.

models.scala

  1. package models
  2. import javax.persistence.{Version, Id}
  3. class User {
  4. @Id var id: String = _
  5. var name: String = _
  6. var addresses: java.util.List[Address] = new java.util.ArrayList()
  7. @Version var version: String = _
  8. override def toString = "User: " + this.id + ", name: " + this.name + ", addresses: " + this.addresses
  9. }
  10. class Address {
  11. var city: String = _
  12. var street: String = _
  13. override def toString = "Address: " + this.city + ", " + this.street
  14. }
  15. class Question {
  16. @Id var id: String = _
  17. var title: String = _
  18. var user: User = _
  19. @Version var version: String = _
  20. override def toString = "Question: " + this.id + ", title: " + this.title + ", belongs: " + user.name
  21. }

test.scala

  1. package models
  2. import com.orientechnologies.orient.core.id.ORecordId
  3. import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery
  4. import scala.collection.JavaConverters._
  5. import scala.collection.JavaConversions._
  6. import com.orientechnologies.orient.`object`.db.{OObjectDatabaseTx,OObjectDatabasePool}
  7. import com.orientechnologies.orient.core.db.`object`.ODatabaseObject
  8. object Test {
  9. implicit def dbWrapper(db: OObjectDatabaseTx) = new {
  10. def queryBySql[T](sql: String, params: AnyRef*): List[T] = {
  11. val params4java = params.toArray
  12. val results: java.util.List[T] = db.query(new OSQLSynchQuery[T](sql), params4java: _*)
  13. results.asScala.toList
  14. }
  15. }
  16. def main(args: Array[String]) = {
  17. // ~~~~~~~~~~~~~ create db ~~~~~~~~~~~~~~~~~~~
  18. var uri: String = "plocal:test/orientdb"
  19. var db: OObjectDatabaseTx = new OObjectDatabaseTx(uri)
  20. if (!db.exists) {
  21. db.create()
  22. } else {
  23. db.open("admin", "admin")
  24. }
  25. // ~~~~~~~~~~~~ register models ~~~~~~~~~~~~~~~~
  26. db.getEntityManager.registerEntityClasses("models")
  27. // ~~~~~~~~~~~~~ create some data ~~~~~~~~~~~~~~~~
  28. var user: User = new User
  29. user.name = "aaa"
  30. db.save(user)
  31. var address1 = new Address
  32. address1.city = "NY"
  33. address1.street = "road1"
  34. var address2 = new Address
  35. address2.city = "ST"
  36. address2.street = "road2"
  37. user.addresses += address1
  38. user.addresses += address2
  39. db.save(user)
  40. var q1 = new Question
  41. q1.title = "How to use orientdb in scala?"
  42. q1.user = user
  43. db.save(q1)
  44. var q2 = new Question
  45. q2.title = "Show me a demo"
  46. q2.user = user
  47. db.save(q2)
  48. // ~~~~~~~~~~~~~~~~ count them ~~~~~~~~~~~~~~~~
  49. val userCount = db.countClass(classOf[User])
  50. println("User count: " + userCount)
  51. val questionCount = db.countClass(classOf[Question])
  52. println("Question count: " + questionCount)
  53. // ~~~~~~~~~~~~~~~~~ get all users ~~~~~~~~~~~~
  54. val users = db.queryBySql[User]("select from User")
  55. for (user <- users) {
  56. println(" - user: " + user)
  57. }
  58. // ~~~~~~~~~~~~~~~~~~ get the first user ~~~~~~~~
  59. val firstUser = db.queryBySql[User]("select from User limit 1").head
  60. println("First user: " + firstUser)
  61. // query by id
  62. val userById = db.queryBySql[User]("select from User where @rid = ?", new ORecordId(user.id))
  63. println("User by id: " + userById)
  64. // query by field
  65. val userByField = db.queryBySql[User]("select from User where name = ?", user.name)
  66. println("User by field: " + userByField)
  67. // query by city
  68. val userByCity = db.queryBySql[User]("select from User where addresses contains ( city = ? )", "NY")
  69. println("User by city: " + userByCity)
  70. // query questions of the user
  71. val questions = db.queryBySql[Question]("select from Question where user = ?", user)
  72. for (q <- questions) {
  73. println(" - question: " + q)
  74. }
  75. db.drop()
  76. db.close()
  77. }
  78. }