NHibernate 警告 Narrowing proxy to - this operation breaks ==
NHibernate warning Narrowing proxy to - this operation breaks ==
我对 NHibernate 中的代理有疑问。我的日志文件中有很多日志,例如:将代理范围缩小到 - 此操作中断 ==
网上还有一些其他问题和不同的答案:
Whosebug NHibernate narrowing proxy warning It being a big deal or not depends on the level of risk you are willing to accept. Since there is going to always been a disconnect between your code and your database you can not always assure that the casting will work. This will lead to bugs that might be difficult to diagnose and may not be resolved without changes to the database or the code.
来自休眠的另一个 post:
Narrowing problem Don't worry about his warning, just put the following in your log file and you shouldn't see it anymore...
Why it happens?
Suppose you have a Product with a many-to-one association to Address. Both are entities and Address has a ShippingAddress subclass.
Let's Session.get(..) a Product from the db that has ShippingAddress as association. Because the many-to-one is lazy, it will return a Address proxy. Note that this is a Address proxy and not a ShippingAddress proxy as the proxy will always match the type that is mentioned in Product (see the hibernate book for details).
This proxy is stored by Hibernate in his proxy cache.
Now we Session.get(...) the same ShippingAddress from the db, the one that is associated to the Product that we used fetched from the db.
Now Hibernate will see that it already contains a proxy for this ShippingAddress and will return this. However, it will notice that the types aren't the same so a "downcasting" must occur. Because this latter action isn't possible with "proxies" it will create new one and return it...
As you can see, nothing to worry about.
You could consider making the Address a value type...
In my case that's no option.
还有最后一个
这是来自 NHibernate 的代码:StatefulPersistenceContext.cs -> NarrowProxy(..)
那么,有没有问题?我总是在我的程序中使用分离的对象。
我希望有一个人可以帮助我。
非常感谢。
如果您使用 ==
运算符比较实体并确定它们是否相同,这可能会很麻烦。
当您将实体添加到映射为 set
的集合时,这确实会发生类似的情况(但确实是 Equals
)。如果该集合恰好已经包含实体但通过另一个代理类型实例化,add
可能 无法遵守其合同,它可能会再次添加实体,并且 set
将包含同一实体的两次出现。
这是可能,而不是将,因为您可以通过覆盖Equals
(和GetHashcode
,因为必须在您的实体上 return 相同的对象哈希码),以便通过它们的主键和实体类型进行比较。对于 set
,这就足够了(因为它不使用 ==
运算符,而是使用 Equals
方法,如果您的类型实现了它,则优先考虑 IEquatable<T>
中的那个)。
对于 ==
,您需要在 class 上定义 ==
和 !=
运算符以使用您的 Equals
实现。
阅读 here or here for more on this. Beware, their example implementations are just examples, and are not suitable for a domain model using inheritance. Read here for a overriding example handling inheritance. (But it does not handle transient entities: better append to it a final test on natural ids if they have one, rather than yielding false if both are considered transient while being not the same reference.) And this blog provides a base class with ==
redefined (found in this Stack Overflow question).
使用分离的实体会增加这种风险。如果您还没有在您的实体上重写这两个方法,那么无论此警告如何,这样做都会更安全。
我对 NHibernate 中的代理有疑问。我的日志文件中有很多日志,例如:将代理范围缩小到 - 此操作中断 == 网上还有一些其他问题和不同的答案:
Whosebug NHibernate narrowing proxy warning It being a big deal or not depends on the level of risk you are willing to accept. Since there is going to always been a disconnect between your code and your database you can not always assure that the casting will work. This will lead to bugs that might be difficult to diagnose and may not be resolved without changes to the database or the code.
来自休眠的另一个 post:
Narrowing problem Don't worry about his warning, just put the following in your log file and you shouldn't see it anymore...
Why it happens? Suppose you have a Product with a many-to-one association to Address. Both are entities and Address has a ShippingAddress subclass.
Let's Session.get(..) a Product from the db that has ShippingAddress as association. Because the many-to-one is lazy, it will return a Address proxy. Note that this is a Address proxy and not a ShippingAddress proxy as the proxy will always match the type that is mentioned in Product (see the hibernate book for details).
This proxy is stored by Hibernate in his proxy cache. Now we Session.get(...) the same ShippingAddress from the db, the one that is associated to the Product that we used fetched from the db. Now Hibernate will see that it already contains a proxy for this ShippingAddress and will return this. However, it will notice that the types aren't the same so a "downcasting" must occur. Because this latter action isn't possible with "proxies" it will create new one and return it...
As you can see, nothing to worry about. You could consider making the Address a value type... In my case that's no option.
还有最后一个
这是来自 NHibernate 的代码:StatefulPersistenceContext.cs -> NarrowProxy(..)
那么,有没有问题?我总是在我的程序中使用分离的对象。 我希望有一个人可以帮助我。 非常感谢。
如果您使用 ==
运算符比较实体并确定它们是否相同,这可能会很麻烦。
当您将实体添加到映射为 set
的集合时,这确实会发生类似的情况(但确实是 Equals
)。如果该集合恰好已经包含实体但通过另一个代理类型实例化,add
可能 无法遵守其合同,它可能会再次添加实体,并且 set
将包含同一实体的两次出现。
这是可能,而不是将,因为您可以通过覆盖Equals
(和GetHashcode
,因为必须在您的实体上 return 相同的对象哈希码),以便通过它们的主键和实体类型进行比较。对于 set
,这就足够了(因为它不使用 ==
运算符,而是使用 Equals
方法,如果您的类型实现了它,则优先考虑 IEquatable<T>
中的那个)。
对于 ==
,您需要在 class 上定义 ==
和 !=
运算符以使用您的 Equals
实现。
阅读 here or here for more on this. Beware, their example implementations are just examples, and are not suitable for a domain model using inheritance. Read here for a overriding example handling inheritance. (But it does not handle transient entities: better append to it a final test on natural ids if they have one, rather than yielding false if both are considered transient while being not the same reference.) And this blog provides a base class with ==
redefined (found in this Stack Overflow question).
使用分离的实体会增加这种风险。如果您还没有在您的实体上重写这两个方法,那么无论此警告如何,这样做都会更安全。