Db4o поддерживает java.util.Calendar
объекты, но не из коробки. Чтобы добавить поддержку Calendar
, добавьте одну из этих двух строк в конфигурацию базы данных:
configuration.common().objectClass(Calendar.class).callConstructor(true);
или
configuration.common().objectClass(Calendar.class).storeTransientFields(true);
Причина, по которой это необходимо, состоит в том, что Calendar
имеет transient
поля или поля, которые не сохраняются или не сериализуются по умолчанию в Java ( JLS §8.3.1.3 ). Вы можете найти эти поля в Calendar
исходном коде , если хотите. Эти поля обычно зависят от какого-либо другого поля в объекте и вычисляются при изменении значения другого поля. Из раздела JLS выше:
Переменные могут быть помечены transient
, чтобы указать, что они не являются частью постоянного состояния объекта.
Например, допустим, у меня есть класс, представляющий продажу:
public class Sale {
private double cost, taxRate;
private transient double taxesPaid;
// etc...
}
Я объявил здесь переменную taxesPaid
как переходную, потому что могу понять это из cost
и taxRate
. Если стоимость составляет 2,00 доллара США, а ставка налога составляет 7%, то уплаченные налоги составят 0,14 доллара США. В базах данных этот вид информации обычно считается избыточным, и есть целые книги, написанные о том, как удалить этот вид зависимости из базы данных. В Java вы можете указать, что поле не будет сохраняться вообще, указав его как transient
.
Db4o соблюдает определение переходных полей в Java и не будет их хранить. Фактически, большинство постоянных структур и баз данных не будут хранить временные поля. Таким образом, когда db4o воссоздает объект Calendar
из базы данных, он только восстанавливает свои непереходные поля, что означает, что все переходные поля равны null
(следовательно, ваш NullPointerException
). Чтобы это исправить, вы указываете db4o либо:
- Вызовите конструктор
Calendar
, и конструктор Calendar
автоматически инициализирует / вычислит переходные поля или
- Сохраните
Calendar
переходные поля, которые будут обрабатывать поля, как если бы они не были переходными.
Кстати, я видел, как люди рекомендуют использовать обе строки в своем коде, и я также видел GregorianCalendar.class
вместо Calendar.class
. Хотя один или другой должен работать нормально.
Извините за взвешивание в конце. Я просто подумал, что важно убедиться, что любой, кто читает это, знает, что это правильный способ хранения Calendar
(он позволяет индексировать, запрашивать и т. Д. В полях Calendar
без создания объектов, замедляющих запросы).