我对NHibernate中的代理有疑问。我在我的日志文件里面有很多日志,比如:缩小代理到 - 这个操作会破坏== 网上还有一些其他问题和不同答案:
Stackoverflow NHibernate narrowing proxy warning 这是一个大问题取决于您愿意接受的风险级别。由于您的代码与数据库之间始终存在脱节现象不能总是保证铸件会起作用。 这将导致可能难以诊断的错误,如果不更改数据库或代码,可能无法解决。
来自hibernate的另一篇文章:
Narrowing problem 不要担心他的警告,只需将以下内容放入您的日志文件中,您就不应该再看到它了......
为什么会这样? 假设您有一个与地址有多对一关联的产品。两者都是实体,Address具有ShippingAddress子类。
让Session.get(..)从具有ShippingAddress作为关联的数据库中获取产品。因为多对一是懒惰的,它将返回一个地址代理。请注意,这是一个地址代理而不是ShippingAddress代理,因为代理将始终与Product中提到的类型匹配(有关详细信息,请参阅hibernate手册)。
此代理由Hibernate存储在其代理缓存中。 现在我们Session.get(...)来自db的相同ShippingAddress,它与我们从db中获取的Product关联的那个。 现在,Hibernate将看到它已包含此ShippingAddress的代理并将返回此信息。但是,它会注意到这些类型并不相同,所以"向下转换"必须发生。因为后面的行为是不可能的,因为代理"它会创建一个并返回它......
如您所见,无需担心。 您可以考虑将地址设为值类型... 在我的情况下,没有选择。
最后一个
以下是来自NHibernate的代码:StatefulPersistenceContext.cs -> NarrowProxy(..)
那么,这是一个问题吗?我总是在我的程序中使用分离的对象。 我希望有一个人可以帮助我。 非常感谢。
答案 0 :(得分:1)
如果您使用==
运算符来比较实体并确定它们是否相同,则可能会出现问题。
当您将实体添加到映射为Equals
的集合时,会发生类似情况(但确实会set
)。如果集合恰好已包含实体但通过其他代理类型实例化,则add
可能无法遵守其合同,它可能会再次添加实体,set
然后会包含同一实体的两次出现。
这是可能,而不是 ,因为您可以通过覆盖Equals
(和GetHashcode
来避免此问题,因为它是必须在您的实体上返回相同对象的相同哈希码,以便通过它们的主键和实体类型进行比较。对于set
,它就足够了(因为它不使用==
运算符,而是使用Equals
方法,如果您的类型实现了IEquatable<T>
,则优先考虑==
。< / p>
对于==
,您需要在班级中定义!=
和Equals
运算符,以便使用==
实现。
有关详情,请阅读here或here。请注意,他们的示例实现只是示例,并不适合使用继承的域模型。阅读here以获取处理继承的重写示例。 (但它不处理瞬态实体:如果它们有一个,最好在natural ids上附加一个最终测试,而不是假设两个被认为是瞬态而不是同一个引用,则产生错误。)这个{{3} }提供了一个重新定义 function initialize() {
var latlng = new google.maps.LatLng(40.716948, -74.003563);
var options = { zoom: 14, center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP};
var map = new google.maps.Map(document.getElementById("map_canvas"), options);
}
initialize();
的基类(在此blog中找到)。
使用分离的实体会增加此风险。如果您还没有在实体上覆盖这两种方法,那么无论发出此警告,都会更安全。