Недавно я обновил свое приложение Play Framework с 2.6 до 2.7. Первоначально я хотел избежать этого обновления, но у Akka Cluster Bootstrap есть минимальные требования к версии Akka 2.5.21, которые выполняются игровой инфраструктурой 2.7. Так что я думаю, что был вынужден обновить свое приложение для игры.

Согласно документации, я считаю, что версия 2.7 в основном отличается от 2.6 в Java API. Я чувствую, что мое приложение scala должно быть в порядке на 90%, что так и есть. Тем не менее, у меня все еще было несколько ошибок, о которых я подробно расскажу ниже.

Плавное обновление до 3.3.0

Согласно документу по гладкой миграции, версия 3.3.0 включает встроенную поддержку типа данных java.time. Это звучит как отличная новость, больше нет MappedColumnType для этих стандартных типов данных!

К сожалению, эта поддержка java.time создает больше проблем, чем что-либо другое. Честно говоря, я думаю, что это как-то связано с дизайном профиля postgres. Проблема в:

Профиль Slick postgres использует PGObject для связи с базой данных. Эта функция поддерживается драйвером JDBC postgres. Однако это мешает вам использовать коды базы данных H2 в режиме Postgres. По очевидной причине: H2 ничего не знает о PGObject.

Проверяя репозиторий Slick на github, вы можете найти людей, которые обсуждают возможность сделать эту функцию java.time необязательной.

В любом случае, если вы видите такую ​​ошибку после обновления, читайте дальше.

Cannot parse "TIMESTAMP" constant "aced0005740018323031392d30352d30325430343a35323a32382e3735315a"; SQL statement:
update "security_user_passwords" set "user_id" = ?, "hasher" = ?, "salt" = ?, "password" = ?, "updated_by" = ?, "updated_at" = ? where "security_user_passwords"."user_id" = 'u3' [22007-199]

В моей кодовой базе я использовал Instant для всего поля времени. Вот что я сделал в своем приложении.

Приведенные выше коды в основном создают новый мой собственный профиль и используют стандартные setTimestamp / getTimemstamp для работы с механизмом базы данных, где тип базы данных TIMESTAMP используется как в postgresql, так и в H2.

Вы должны импортировать его, а не профиль по умолчанию, чтобы ваше приложение могло использовать наш новый профиль.

Также имейте в виду, что приведенные выше коды потеряют точность в наносекундах на H2. Я уверен, что есть способ исправить это, но, боюсь, наносекунды не очень критичны в моем случае.

На мой взгляд, очень хорошая практика для всех гладких проектов:

Всегда создавайте и используйте свой собственный профиль. Это окажется очень удобным, к тому же можно свести к минимуму импорт и хранить имплициты в одном месте.

Эволюция стала очень шумной

Второе, что я заметил, это то, что сценарии Evolution были напечатаны. Эволюция была выполнена практически для всех моих тестовых случаев. Я должен признать, что это немного разочаровывает и, возможно, немного раздражает, видя, что несколько тысяч сценариев эволюции печатаются каждый раз, когда выполняются тестовые примеры. Это не ошибка, но может сильно отвлечь вас при попытке диагностировать сбой модульного теста.

Добавьте ниже в свой logback.xml, чтобы отключить его

<!-- Hide the evolution details when testing -->
<logger name="play.api.db.evolutions" level="INFO" />

Scala-guice перестает работать в некоторых сложных универсальных случаях

Scala-guice был обновлен до 4.2.3 для поддержки guice 4.2.2. Следующее работало в 4.1.1, но не работало в 4.2.3.

bind[GenericObjectPool[StatefulRedisConnection[String, Array[Byte]]]]
  .toProvider[StringBytesRedisConnectionPoolProvider]
  .in[Singleton]

Чтобы исправить это, я должен вернуться к приведенному ниже стандартному синтаксису guice.

type RedisConnection = StatefulRedisConnection[String, Array[Byte]]
bind[RedisConnectionPool](new TypeLiteral[RedisConnectionPool](){})
  .toProvider(classOf[StringBytesRedisConnectionPoolProvider])
  .in(classOf[Singleton])

Другие привязки scala-guice были в порядке. Я предполагаю, что это проблема только некоторых действительно сложных универсальных типов.

Связано, но не обязательно

Обновите версию H2 до 1.4.199.

Я также обновил его просто потому, что 1.4.199 — последняя доступная версия. Однако чувствительность к регистру, или, лучше сказать, способ указать чувствительность к регистру, изменилась с 1.4.194 на 1.4.199.

URL БД до (1.4.194)

jdbc:h2:mem:test;DATABASE_TO_UPPER=FALSE;MODE=PostgreSQL;DB_CLOSE_DELAY=-1

URL БД после (1.4.199)

jdbc:h2:mem:test;DATABASE_TO_LOWER=TRUE;MODE=PostgreSQL;DB_CLOSE_DELAY=-1

Если ваш сценарий эволюции не смог найти столбец, который явно существует, проверьте настройки учета регистра.

Эта версия H2 также использует некоторые новые зарезервированные слова, например, «интервал». Тщательно создавайте свой код, чтобы обойти его. Самое простое решение — заключить в двойные кавычки идентификатор столбца в любом необработанном операторе SQL.

Вывод

В целом, я доволен процессом обновления этой версии. Документы были очень четкими и точными. Устаревшие были объявлены заранее и выполнялись постепенно, чтобы сделать процесс очень плавным. С другой стороны, я до сих пор не вижу веских причин для обновления play framework 2.7, особенно для scala-приложений. Взвешивание вариантов и проблем, с которыми вы сталкиваетесь, прежде чем принять решение о миграции.

sohoffice, удачного кодирования ~

Вы узнали что-то новое? Если да, пожалуйста:

кнопка хлопать 👏 ниже️, чтобы это увидело больше людей.