Другое событие NullPointerException
возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.
String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals
для гарантированного непустого объекта.
Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null
.
Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.
String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Существует несколько хороших вариантов. Я не использовал бы "восстановление резервная" стратегия.
Сценарий все Ваши изменения схемы, и имеют Ваш сервер CI, выполняет те сценарии на базе данных. Имейте таблицу версии, чтобы отслеживать текущую версию базы данных, и только выполнить сценарии, если они для более новой версии.
Использование решение для миграции. Эти решения варьируются языком, но для.NET я использую Migrator.NET. Это позволяет Вам присваивать версию своей базе данных и перемещению вверх и вниз между версиями. Ваша схема определяется в коде C#.
Ваши разработчики должны записать сценарии изменения (схема и изменение данных) для каждой ошибки/функции, они продолжают работать, не просто выводят всю базу данных в управление исходным кодом. Эти сценарии обновят текущую производственную базу данных до новой версии в разработке.
Ваш процесс сборки может восстановить копию производственной базы данных в соответствующую среду и выполнить все сценарии от управления исходным кодом на ней, которое обновит базу данных к текущей версии. Мы делаем это ежедневно для проверки всех сценариев, выполненных правильно.
Взгляните на то, как Ruby on Rails делает это.
Первый существуют так называемые файлы миграции, которые в основном преобразовывают схему базы данных и данные от версии N до версии N+1 (или в случае понижения от версии N+1 до N). База данных имеет таблицу, которая говорит текущую версию.
базы данных Test всегда вытираются чистые перед модульными тестами и заполняются с фиксированными данными из файлов.
Книжные Базы данных Рефакторинга: Эволюционное Проектирование баз данных могло бы дать Вам некоторое представление относительно того, как управлять базой данных. Короткая версия читаема также в http://martinfowler.com/articles/evodb.html
В одном проекте PHP+MySQL, у меня было число пересмотра базы данных, сохраненное в базе данных, и когда программа соединится с базой данных, это сначала проверит пересмотр. Если программа потребует другого пересмотра, то она откроет страницу для обновления базы данных. Каждое обновление указано в коде PHP, который изменит схему базы данных и переместит все существующие данные.
Вы могли также посмотреть на использование инструмента как , SQL Выдерживает сравнение для сценариев различия между различными версиями базы данных, позволяя Вам быстро мигрировать между версиями
Это - что-то, что я постоянно не удовлетворен с - наше решение этой проблемы, которая является. В течение нескольких лет мы поддержали отдельный сценарий изменения для каждого выпуска. Этот сценарий содержал бы дельты от последнего производственного выпуска. С каждым выпуском приложения номер версии увеличил бы, дав что-то как следующее:
Это работало достаточно хорошо, пока мы не начали поддерживать две строки разработки: соединительная линия/Магистраль для новой разработки, и ответвление обслуживания для исправлений ошибок, краткосрочные улучшения, и т.д. Неизбежно, потребность возникла для внесения изменений в схему в ответвлении. На данном этапе у нас уже был dbChanges_n+1.sql в Соединительной линии, таким образом, мы закончили тем, что шли со схемой как следующее:
Снова, это работало достаточно хорошо, пока мы однажды мы не искали и видели 42 сценария дельты в магистрали и 10 в ответвлении. ARGH!
В эти дни мы просто поддерживаем один сценарий дельты и позволяем версии SVN это - т.е. мы перезаписываем сценарий с каждым выпуском. И мы уклоняемся от внесения изменений схемы в ответвлениях.
Так, я не удовлетворен этим также. Мне действительно нравится понятие миграций от направляющих. Я стал вполне очарованным LiquiBase. Это поддерживает понятие возрастающих рефакторингов базы данных. Это достойное внимания, и я буду смотреть на него подробно скоро. У кого-либо есть опыт с ним? Мне было бы очень любопытно услышать о Ваших результатах.
У нас есть очень похожая установка к OP.
Разработчики разрабатывают в VM's с частным DB.
[Разработчики будут скоро фиксировать в частные ответвления]
, Тестирование выполняется на различных машинах (на самом деле в в VM's, размещенном на сервере) [Будет скоро выполнен сервером Hudson CI]
Тест путем загрузки ссылочного дампа в дб. Подайте заявку патчи схемы разработчиков тогда применяют патчи данных разработчиков
Тогда выполненные модульные тесты и тестирование системы.
Производство развертывается на клиентах как установщики.
, Что мы делаем:
Мы берем дамп схемы нашего DB песочницы. Тогда sql дамп данных. Мы разность это к предыдущей базовой линии. та пара дельт должна обновить n-1 до n.
мы настраиваем дампы и дельты.
Так для установки версии N УБИРАЮТ, мы выполняем дамп в пустой дб. Для исправления примените прошедшие патчи.
(Juha упомянул, идея направляющей наличия таблицы, записывающей текущую версию DB, является хорошей и должна сделать обновления установки менее удручающими.)
Дельты и дампы должны быть рассмотрены перед тестированием бета-версии. Я не вижу пути вокруг этого, поскольку я видел, что разработчики вставляют тестовые учетные записи в DB для себя.
Проверьте dbdeploy, существует Java и .net инструменты, уже доступные, Вы могли следовать их стандартам для разметок файла SQL и таблицы версии схемы и записать Вашу версию Python.
Если Вы находитесь в среде.NET тогда, решение Tarantino. Это обрабатывает, все это (включая который sql сценарии установить) в NANT создает.
Я боюсь, что я в согласии с другими плакатами. Разработчики должны написать сценарий своих изменений.
Во многих случаях простой ALTER TABLE не будет работать, необходимо изменить существующие данные также - разработчикам нужно к вещи о том, какие миграции требуются и удостоверяются, что они заданы сценарием правильно (конечно, необходимо протестировать это тщательно в какой-то момент в цикле выпуска).
, Кроме того, если у Вас есть какой-либо смысл, Вы заставите своих разработчиков писать сценарий откатов для своих изменений также, таким образом, они смогут вернуться в случае необходимости. Это должно быть протестировано также, чтобы гарантировать, что их откат не только выполняется без ошибки, но и оставляет DB в том же состоянии, как это было в ранее (это не всегда возможно или желательно, но является хорошим правилом большую часть времени).
, Как Вы сцепляете это в сервер CI, я не знаю. Возможно, Ваш сервер CI должен иметь известный снимок сборки на, который он возвращается к каждой ночи и затем применяет все изменения с тех пор. Это является, вероятно, лучшим, иначе поврежденный сценарий миграции повредит не только сборку той ночи, но и все последующие.
Я записал инструмент, который (путем сцепления в Открывают DBDiff) сравнивает схемы базы данных и предложит сценарии миграции Вам. При внесении изменения, которое удаляет или изменяет данные, это бросит ошибку, но обеспечит предложение для сценария (например, когда столбец в пропавших без вести в новой схеме, это проверит, был ли столбец переименован и создает xx - генерировал script.sql.suggestion, содержащий переименовать оператор).
http://code.google.com/p/migrationscriptgenerator/ SQL Server только я боюсь :( Это - также симпатичная альфа, но это - ОЧЕНЬ низкое трение (особенно при объединении его с Tarantino или http://code.google.com/p/simplescriptrunner/ )
способ, которым я использую его, должен иметь проект сценариев SQL в .sln. У Вас также есть db_next база данных локально, которую Вы вносите своими изменениями в (использование Studio управления или Экспорт Схемы NHibernate или LinqToSql CreateDatabase или что-то). Затем Вы выполняете migrationscriptgenerator с _dev и _next DBS, который создает. сценарии обновления SQL для миграции через.
Если вы не возражаю против автоматизации торговли для простоты, каждая реконфигурация application_layer, которая требует перекомпиляции, - это BAD
Мы используем командную строку mysql-diff : она выводит разницу между двумя схемами базы данных (из реальной БД или скрипта) в виде скрипта ALTER. mysql-diff выполняется при запуске приложения, и если схема изменилась, он сообщает разработчику. Таким образом, разработчикам не нужно писать ALTER вручную, обновления схемы происходят полуавтоматически.