NHibernate 警告正在缩小代理范围 - 此操作会中断 ==

use*_*952 5 c# nhibernate proxy logging warnings

我有一个关于 NHibernate 代理的问题。我的日志文件中有很多日志,例如:将代理缩小到 - 此操作中断==网上还有一些其他问题和不同的答案:

Stackoverflow NHibernate 缩小代理警告 这是否是一件大事取决于您愿意接受的风险程度。由于代码和数据库之间始终存在脱节,因此您无法始终确保转换能够正常工作。这将导致可能难以诊断的错误,并且如果不更改数据库或代码就可能无法解决。

hibernate 的另一篇文章:

缩小问题范围 不要担心他的警告,只需将以下内容放入您的日志文件中,您就不会再看到它了......

为什么会发生这种情况?假设您有一个与地址具有多对一关联的产品。两者都是实体,并且 Address 有一个 ShippingAddress 子类。

让我们从数据库中 Session.get(..) 获取一个以 ShippingAddress 作为关联的产品。因为多对一是惰性的,所以它会返回一个Address代理。请注意,这是一个地址代理,而不是一个 ShippingAddress 代理,因为代理将始终与产品中提到的类型匹配(有关详细信息,请参阅 hibernate 书籍)。

该代理由 Hibernate 存储在其代理缓存中。现在,我们从数据库中 Session.get(...) 获取相同的 ShippingAddress,该地址与我们使用的从数据库中获取的产品相关联。现在 Hibernate 将发现它已经包含此 ShippingAddress 的代理并将返回它。但是,它会注意到类型不相同,因此必须进行“向下转型”。因为后一个操作对于“代理”来说是不可能的,所以它将创建新的操作并返回它......

正如你所看到的,没什么好担心的。 您可以考虑将地址设置为值类型...在我的情况下,这是没有选择的。

还有最后一张

Hibernate 4 中删除了 ProxyWarnLog?

以下是 NHibernate 的代码:StatefulPersistenceContext.cs -> NarrowProxy(..)

那么,到底有没有问题呢?我总是在程序中使用分离的对象。我希望有一个人可以帮助我。多谢。

Fré*_*ric 2

==如果您使用运算符来比较实体并确定它们是否相同,这可能会很麻烦。

Equals您将实体添加到映射为set. 如果该集合碰巧已经包含该实体,但通过另一个代理类型实例化,则add 可能无法遵守其约定,它可能会再次添加该实体,然后该集合set将包含同一实体的两次出现。

这是一个可能,而不是一个意愿,因为您可以通过覆盖实体Equals(并且GetHashcode,因为对于相等的对象必须返回相同的哈希码)来避免这种麻烦,以便通过它们的主键和实体类型来比较它们。对于set,这就足够了(因为它不使用==运算符,而是Equals使用方法,如果您的类型实现了它,则优先使用 from IEquatable<T>)。

对于==,您需要在您的类上定义==!=运算符以使用您的Equals实现。

阅读此处此处了解更多相关信息。请注意,它们的示例实现只是示例,并不适合使用继承的域模型。请阅读此处了解处理继承的重要示例。(但它不处理瞬态实体:如果它们有自然 ID ,最好在其上附加一个对自然 id 的最终测试,而不是如果两者都被认为是瞬态的而不是相同的引用,则产生 false。)并且此博客==提供了一个重新定义的基类(在这个堆栈溢出问题中找到)。

与独立实体合作会增加这种风险。如果您尚未在实体上重写这两种方法,那么无论此警告如何,这样做都会更安全。