Как будто вы пытаетесь получить доступ к объекту, который является null
. Рассмотрим ниже пример:
TypeA objA;
. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException
, что имеет смысл.
См. Также этот пример:
String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
Вы получаете круговую ошибку зависимости? Как Вы игнорируете объекты от сериализации?
, Так как ленивая загрузка генерирует объекты прокси, будут потеряны любые атрибуты, которые имеют Ваши участники класса. Я столкнулся с той же проблемой с JSON-сериализатором Newtonsoft, так как объект прокси больше не имел [JsonIgnore] атрибутов.
Вы, вероятно, захотите к нетерпеливой загрузке большую часть объекта так, чтобы это могло быть сериализировано:
ICriteria ic = _session.CreateCriteria(typeof(Person));
ic.Add(Restrictions.Eq("Id", id));
if (fetchEager)
{
ic.SetFetchMode("Person", FetchMode.Eager);
}
А хороший способ сделать это должно добавить bool к конструктору (bool isFetchEager) Вашего метода поставщика данных.
Я использую NHibernate с Json.NET и заметил, что получаю необъяснимые свойства «__interceptors» в моих сериализованных объектах. Поиск в Google обнаружил это отличное решение Ли Хенсона, которое я адаптировал для работы с Json.NET 3.5 Release 5.
public class NHibernateContractResolver : DefaultContractResolver
{
private static readonly MemberInfo[] NHibernateProxyInterfaceMembers = typeof(INHibernateProxy).GetMembers();
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
{
var members = base.GetSerializableMembers(objectType);
members.RemoveAll(memberInfo =>
(IsMemberPartOfNHibernateProxyInterface(memberInfo)) ||
(IsMemberDynamicProxyMixin(memberInfo)) ||
(IsMemberMarkedWithIgnoreAttribute(memberInfo, objectType)) ||
(IsMemberInheritedFromProxySuperclass(memberInfo, objectType)));
var actualMemberInfos = new List<MemberInfo>();
foreach (var memberInfo in members)
{
var infos = memberInfo.DeclaringType.BaseType.GetMember(memberInfo.Name);
actualMemberInfos.Add(infos.Length == 0 ? memberInfo : infos[0]);
}
return actualMemberInfos;
}
private static bool IsMemberDynamicProxyMixin(MemberInfo memberInfo)
{
return memberInfo.Name == "__interceptors";
}
private static bool IsMemberInheritedFromProxySuperclass(MemberInfo memberInfo, Type objectType)
{
return memberInfo.DeclaringType.Assembly == typeof(INHibernateProxy).Assembly;
}
private static bool IsMemberMarkedWithIgnoreAttribute(MemberInfo memberInfo, Type objectType)
{
var infos = typeof(INHibernateProxy).IsAssignableFrom(objectType)
? objectType.BaseType.GetMember(memberInfo.Name)
: objectType.GetMember(memberInfo.Name);
return infos[0].GetCustomAttributes(typeof(JsonIgnoreAttribute), true).Length > 0;
}
private static bool IsMemberPartOfNHibernateProxyInterface(MemberInfo memberInfo)
{
return Array.Exists(NHibernateProxyInterfaceMembers, mi => memberInfo.Name == mi.Name);
}
}
Чтобы использовать его, просто поместите экземпляр в свойство ContractResolver вашего JsonSerializer. Проблема циклической зависимости, отмеченная jishi, может быть решена путем установки для свойства ReferenceLoopHandling значения ReferenceLoopHandling.Ignore. Вот метод расширения, который можно использовать для сериализации объектов с помощью Json.Net
public static void SerializeToJsonFile<T>(this T itemToSerialize, string filePath)
{
using (StreamWriter streamWriter = new StreamWriter(filePath))
{
using (JsonWriter jsonWriter = new JsonTextWriter(streamWriter))
{
jsonWriter.Formatting = Formatting.Indented;
JsonSerializer serializer = new JsonSerializer
{
NullValueHandling = NullValueHandling.Ignore,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
ContractResolver = new NHibernateContractResolver(),
};
serializer.Serialize(jsonWriter, itemToSerialize);
}
}
}
У нас была именно эта проблема, которая была решена благодаря ответу Мастера здесь.
Проблема возникает из-за того, что JSON.NET не понимает, как сериализовать прокси-классы NHibernate. Решение: сериализуйте экземпляры прокси, как их базовый класс.
Упрощенная версия кода Handcraftsman выглядит следующим образом:
public class NHibernateContractResolver : DefaultContractResolver {
protected override List<MemberInfo> GetSerializableMembers(Type objectType) {
if (typeof(INHibernateProxy).IsAssignableFrom(objectType)) {
return base.GetSerializableMembers(objectType.BaseType);
} else {
return base.GetSerializableMembers(objectType);
}
}
}
IMHO, этот код имеет то преимущество, что по-прежнему полагается на поведение JSON.NET по умолчанию в отношении настраиваемых атрибутов и т. Д. (И код намного короче!).
Он используется так
var serializer = new JsonSerializer{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
ContractResolver = new NHibernateContractResolver()
};
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new Newtonsoft.Json.JsonTextWriter(stringWriter);
serializer.Serialize(jsonWriter, objectToSerialize);
string serializedObject = stringWriter.ToString();
Примечание: Этот код был написан и использовался с NHibernate 2.1. Как отмечали некоторые комментаторы, это не работает из коробки с более поздними версиями NHibernate, вам придется внести некоторые изменения. Я постараюсь обновить код, если мне когда-нибудь придется сделать это с более поздними версиями NHibernate.