Некоторое время назад я приступил к задаче создания своего первого полноценного сервера Scala. У меня было несколько решений, чтобы сделать:
- Магазин постоянства
- Постоянство Рамки
- Сервер приложений
Использование NoSql в основном удалило все связанные с JPO фреймворки из таблицы (что я считаю хорошей вещью). Любовь к Spring, как и я, привела меня к выбору Spring-data в качестве основы постоянства. Казалось, что приличная поддержка Монго.
Для сервера приложений я решил положиться на прошлые успехи и использовал Jetty 9.
Настроить монго было довольно легко. Поскольку я использовал Scala, я хотел использовать case-классы в качестве моей модели. Цель состояла в том, чтобы использовать одни и те же объекты для моего слоя REST, используя модуль Jackson Scala, с одной стороны, и иметь возможность записать один и тот же тип объекта в моем хранилище постоянства.
Spring-данные поначалу выглядели многообещающе. Я смог отправить Json, конвертировать в мою объектную модель прозрачно, используя следующий фрагмент XML:
<mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper" ref="mapper"/> </bean> </mvc:message-converters> </mvc:annotation-driven>
Картограф был экземпляром Джексона-модуля-Скала . Все идет нормально.
Я заметил одну странную вещь. Spring не знал, как сериализовать мои классы case из коробки (очевидно), поэтому он использовал универсальный сериализатор классов при записи моих объектов в Mongo. это работало достаточно хорошо, читая состояние обратно в объект, пока я не попал в showtopper.
Очевидно, классы case, которые содержали Scala ‘Option’, не были десериализованы должным образом. Например, рассмотрим следующий код:
myOptionField match { case Some(value) => do something case None => do something else }
Оказывается, он никогда не доходил до сегмента «дела нет». Чтение моего состояния из Монго, хотя сериализовано как None, привело к нарушению вышесказанного Единственным обходным решением было сделать что-то вроде этого:
myOptionField match { case Some(value) => do something case _=> do something else }
Это, конечно, было не оптимально.
Если этого было недостаточно, в некоторых случаях, когда нам приходилось использовать последовательные поля опций Scala, мы получали странные ошибки сериализации Json:
com.fasterxml.jackson.databind.JsonMappingException: (None,None) (of class scala.Tuple2)
Хммм. Я не чувствую себя комфортно с текущим состоянием …
Поскольку мой проект был молодым, мне повезло, что я смог изменить его. К счастью, у меня был изолированный db-слой, который позволил мне довольно легко вернуться к моему решению Persistence Framework.
Читая еще немного, я обнаружил, что у Mongo есть официальный драйвер Scala (как же я пропустил это?) Ницца. Но ждать. Начав реализовывать переход от Spring-Data к Casbah-драйверу Scala, быстро выяснилось, что я не могу передать свои кейс-классы в Scala-драйвер. Он использует только объекты MongoDB. О чувак. Действительно ли мне нужно создавать читателей и писателей для всех моих 20+ тематических классов?
Ну нет.
Салат на помощь. Наконец, аккуратное решение. Я могу легко конвертировать мои классы дел в монго и обратно, используя лаконичный и легко читаемый код:
val mongodbConnetion = MongoConnection(host,port) val mydb = mongodbConnetion("mydb") mydb.writeConcern = WriteConcern.FsyncSafe val my-coll-db = mydb("my-coll-db") //insert new document my-coll-db.insert(grater[MyCaseClassObject].asDBObject(myObj))
Вот и все. Легко использовать. Легко читать. Учись писать.
Подводя итог, можно сказать, что данные Spring (как ни крути) не подходят для работы с Scala. К счастью, у нас есть хорошие альтернативы.