如何覆盖特定NHibernate类的equals

时间:2021-02-23 16:11:54

I am struggling to figure out how I should override equals and get hashcode for a class I am writing using NHibernate.

我正在努力弄清楚我应该如何覆盖equals并获取我使用NHibernate编写的类的哈希码。

Basic business scenario is that users cannot re-use the same password within a 90 day limit.

基本业务场景是用户无法在90天限制内重复使用相同的密码。

So I have a "user" that has many "historical passwords"... the user class was easy as I just use the login in the equals. Below is my HistoricalPassword class.

所以我有一个“用户”,它有许多“历史密码”......用户类很容易,因为我只是在等号中使用登录。下面是我的HistoricalPassword类。

public class HistoricalPassword
{
    public virtual int HistoricalPasswordId { get; set; }
    public virtual User User { get; set; }
    public virtual DateTime ChangeDate { get; set; }
    public virtual string FormerPassword { get; set; }
}

I would say from a business sense that the combination of the User and the ChangeDate would give me equality. However... it does not seem correct to reference the user in the equals method (since for one thing that would cause a lazy load to happen)... and also from what I read using the PK of HistoricalPasswordId is a no-no as well.

从商业意义上说,用户和ChangeDate的组合会让我平等。但是...在equals方法中引用用户似乎不正确(因为有一件事会导致延迟加载发生)......而且我从使用HistoricalPasswordId的PK读取的内容也是一个禁忌同样。

Can anyone provide some advice on how they would override equals for this?

任何人都可以提供一些建议,他们将如何覆盖等于此?

EDIT ::: I think I might have been a little misleading on the way I asked the question. I'm not confused on how to enforce the business rule of making sure the passwords are not reused... nor on how I know if two passwords are equal or are secure. What I really want to know is at the entity level specifically relating to NHibernate how would I override Equals for this object so that NHibenate does not end up with dupes in the session and/or cache. According to the NHibernate doc (https://www.hibernate.org/hib_docs/nhibernate/html/persistent-classes.html) I should override equals using Business key equality. In this case I'm just not sure if using the referenced object of User in the compare is a good idea.

编辑:::我想我可能在提出问题的方式上有点误导。我并不担心如何执行确保密码不被重用的业务规则...也不知道如何知道两个密码是否相等或是否安全。我真正想知道的是在与NHibernate有关的实体级别如何为这个对象重写Equals,以便NHibenate不会在会话和/或缓存中结束dupe。根据NHibernate doc(https://www.hibernate.org/hib_docs/nhibernate/html/persistent-classes.html),我应该使用Business key equality来覆盖equals。在这种情况下,我只是不确定在比较中使用User的引用对象是一个好主意。

3 个解决方案

#1


I wouldn't override Equals for this - you aren't asserting that these records are equal, merely that they reference the same password, aren't you?

我不会为此重写Equals - 你没有断言这些记录是相同的,只是他们引用相同的密码,不是吗?

Surely you just need an HQL or criteria query that gives you the historical passwords set within the last 90 days?

当然,您只需要一个HQL或条件查询,它可以为您提供过去90天内设置的历史密码?

EDIT: Also you might want to check how you are storing your password. Plaintext passwords in the database are not a good idea. It may be that you have an NHibernate user type that is decrypting an encrypted password into the string property we can see, of course...

编辑:您也可以查看如何存储密码。数据库中的明文密码不是一个好主意。您可能有一个NHibernate用户类型正在将加密密码解密为我们可以看到的字符串属性,当然......

#2


I would regard the HistoricalPassword to be a value object, not an entity.

我认为HistoricalPassword是一个值对象,而不是一个实体。

So, this means that it's 'ID' would be determined by the value of all its properties.

所以,这意味着它的'ID'将由其所有属性的值决定。

#3


Couple of ways you could go about this.

你有几种方法可以解决这个问题。

If you want to do it using equality, then the user will be involved, specifically the PK of the user. Equality would be the user PK + the password. Date wouldn't matter. This probably over complicates things, however, and I probably wouldn't go about it this way.

如果你想使用相等来做,那么用户将参与其中,特别是用户的PK。平等将是用户PK +密码。日期无关紧要。然而,这可能使事情变得复杂,我可能不会这样做。

Another way is to use just the password for equality, since that's what you are comparing against in the end. The user would only be used in the query, ditto the change date.

另一种方法是仅使用密码进行相等,因为这是您最终要比较的内容。用户只能在查询中使用,同样也可以在更改日期使用。

Do an HQL query to get the historical passwords where user = {user} and change date < (today - 90). this will return all of the passwords from the last 90 days for {user}. Once that problem is done, all you would need to do is compare the passwords to see if any match, since you have reduced your result set to only those passwords from the last 90 days for {user}.

执行HQL查询以获取user = {user}的历史密码并更改日期<(today - 90)。这将返回{user}过去90天内的所有密码。一旦完成该问题,您需要做的就是比较密码以查看是否有匹配,因为您已将结果集减少到{user}过去90天内的那些密码。

Finally, as mentioned above, simply do an HQL query for {user} where date changed < 90 and password = {new password}. If you get any results back, you know that password has been used in the last 90 days.

最后,如上所述,只需为{user}执行HQL查询,其中日期更改<90且密码= {新密码}。如果您收到任何结果,则表示密码已在过去90天内使用过。

Finally, as also was mentioned above, these comparisons all assume you're either playing with plaintext passwords or encrypting the new password for comparison against the old ones. Ether way, something has to be done to account for the security of the passwords.

最后,正如上面提到的,这些比较都假设您要么使用明文密码,要么加密新密码以与旧密码进行比较。以太方式,必须采取措施来考虑密码的安全性。

#1


I wouldn't override Equals for this - you aren't asserting that these records are equal, merely that they reference the same password, aren't you?

我不会为此重写Equals - 你没有断言这些记录是相同的,只是他们引用相同的密码,不是吗?

Surely you just need an HQL or criteria query that gives you the historical passwords set within the last 90 days?

当然,您只需要一个HQL或条件查询,它可以为您提供过去90天内设置的历史密码?

EDIT: Also you might want to check how you are storing your password. Plaintext passwords in the database are not a good idea. It may be that you have an NHibernate user type that is decrypting an encrypted password into the string property we can see, of course...

编辑:您也可以查看如何存储密码。数据库中的明文密码不是一个好主意。您可能有一个NHibernate用户类型正在将加密密码解密为我们可以看到的字符串属性,当然......

#2


I would regard the HistoricalPassword to be a value object, not an entity.

我认为HistoricalPassword是一个值对象,而不是一个实体。

So, this means that it's 'ID' would be determined by the value of all its properties.

所以,这意味着它的'ID'将由其所有属性的值决定。

#3


Couple of ways you could go about this.

你有几种方法可以解决这个问题。

If you want to do it using equality, then the user will be involved, specifically the PK of the user. Equality would be the user PK + the password. Date wouldn't matter. This probably over complicates things, however, and I probably wouldn't go about it this way.

如果你想使用相等来做,那么用户将参与其中,特别是用户的PK。平等将是用户PK +密码。日期无关紧要。然而,这可能使事情变得复杂,我可能不会这样做。

Another way is to use just the password for equality, since that's what you are comparing against in the end. The user would only be used in the query, ditto the change date.

另一种方法是仅使用密码进行相等,因为这是您最终要比较的内容。用户只能在查询中使用,同样也可以在更改日期使用。

Do an HQL query to get the historical passwords where user = {user} and change date < (today - 90). this will return all of the passwords from the last 90 days for {user}. Once that problem is done, all you would need to do is compare the passwords to see if any match, since you have reduced your result set to only those passwords from the last 90 days for {user}.

执行HQL查询以获取user = {user}的历史密码并更改日期<(today - 90)。这将返回{user}过去90天内的所有密码。一旦完成该问题,您需要做的就是比较密码以查看是否有匹配,因为您已将结果集减少到{user}过去90天内的那些密码。

Finally, as mentioned above, simply do an HQL query for {user} where date changed < 90 and password = {new password}. If you get any results back, you know that password has been used in the last 90 days.

最后,如上所述,只需为{user}执行HQL查询,其中日期更改<90且密码= {新密码}。如果您收到任何结果,则表示密码已在过去90天内使用过。

Finally, as also was mentioned above, these comparisons all assume you're either playing with plaintext passwords or encrypting the new password for comparison against the old ones. Ether way, something has to be done to account for the security of the passwords.

最后,正如上面提到的,这些比较都假设您要么使用明文密码,要么加密新密码以与旧密码进行比较。以太方式,必须采取措施来考虑密码的安全性。