Допустим, мы хотим построить большую социальную сеть (потому что социальные сети сейчас в моде).Начнем с простого предположения, что любой, кто хочет использовать нашу социальную сеть, должен иметь возможность зарегистрироваться под своим именем, а затем стать друзьями или поссориться с другими людьми, зарегистрированными у нас:
import scala.collection._
class Person (var name: String) {
private val _friends = new mutable.HashSet[Person]
def befriends (p: Person) { _friends+=p }
def fallsOutWith (p: Person) { _friends-=p }
def friends () = _friends toSet
override def toString = name
}
Пока чтотак хорошо:
val brad = new Person("Brad Pitt")
val angelina = new Person("Angelina Jolie")
brad befriends angelina
angelina befriends brad
Хорошие вещи!Последний штрих, давайте посмотрим список всех друзей Брэда:
brad.friends.foreach(println)
Это работает, и мы собираемся покорить мир нашей замечательной социальной сетью, которая на 100% Scala!
Теперь перейдем к скучным техническим деталям.Нам нужно было бы сохранить данные, и db4o кажется хорошим выбором, немного кода:
db store brad // job done!
А затем восстановить Брэда с жесткого диска:
val q = db.query
q.constrain(classOf[Person])
q.descend("name").constrain("Brad Pitt")
val brad = q.execute.get(0)
См.список друзей еще раз ...
brad.friends.foreach(println)
и BANG! NullPointerException !После небольшой отладки выясняется, что основное хранилище данных mutable.HashSet, на которое мы рассчитываем отслеживать друзей, определяется как transient в scala.collection.mutable.FlatHashTable :
@transient protected var table: Array[AnyRef] = new Array(initialCapacity)
и, следовательно, когда мы говорим db4o о сохранении персоны, фактический список друзей не сериализуется.Кажется, что db4o должен использовать вместо readObject и writeObject методы HashSet.
Интересно, есть ли способ сказать db4o, чтобы сериализовать / десериализовать HashSet правильно илиесли есть более подходящая реализация Scala Set, которая подходит для db4o?