哪种选择更好地用于Hibernate中的Equals()和HashCode()方法?

发布于 2025-02-10 09:23:13 字数 607 浏览 3 评论 0 原文

我创建 equals() hashcode()在我的Java应用程序中每个Hibernate Entity中的方法(如果没有继承)。但是,我有点困惑,想确定是否正确定义它。您能澄清以下问题吗?

  1. 在Intellij中,当我使用“生成”功能(通过Alt + Insert)时,有一些模板,例如Intellij默认值,Java 7+等。我应该使用哪个模板?

  2. 使用“生成”功能时,我应该将哪个字段包括在我的 equals()和HashCode()以下实体的方法中?

     @entity
    公共类用户{
    
        @ID
        @generatedValue(策略= generatytype.auto)
        私人长ID;
    
        私有字符串名称;
    
        @column(unique = true)
        私人字符串电子邮件;
    
        // getter,setter,构造函数...
    }
     
  3. 我是否应该使用注释来简单简便的用法,例如 @equalsandhashcode ?还是不是灵活的,我应该明确地实施吗?

I create equals() and hashCode() methods in each Hibernate entity (if there is no inheritance) in my Java app. However, I am a little bit confused and wanted to be sure if I define it properly. Could you please clarify the following issues?

  1. In IntelliJ, when I use the "Generate" feature (via Alt + Insert), there are some templates like IntelliJ Default, Java 7+, etc. Which template should I use?

  2. When using the "Generate" feature, which field should I include in my equals() and hashCode() methods of the following entity?

    @Entity
    public class User {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        private String name;
    
        @Column(unique = true)
        private String email;
    
        // getter, setter, constructor...
    }
    
  3. Should I use annotation for simple and easy usage like @EqualsAndHashCode? Or is it not flexible and should I prefer implementing explicitly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

完美的未来在梦里 2025-02-17 09:23:13

要考虑的一个相当关键的问题是用户对象所代表的内容。

它表示数据库中的一行,

意味着如果 Unid 是未设置的(即您还没有 save() d it),则没有2个用户对象与彼此。毕竟,如果您制作了2个用户实例,请将每个值(除了 id 以外,您不会混乱的事情)将因此证明它们并不相同。但是,要遵守Java规则,如果有参考标识(即 this ==其他),则它们将是相同的。

unid 设置时,唯一决定2 用户对象是否相同的东西是它们的UNID相同。所有其他属性都是无关的 - 毕竟,如果您查询相同的DB对同一行(获得每个值相同的用户实例,则具有相同的值),然后您 setemail 在其中一个,然后电子邮件字段不再相同,但这没关系:他们指的是同一行,保存一个和其他更改,因此,它们相同的。

结论:编写自己的等值方法,看起来像:

if (other == null) return false;
if (other.getClass() != User.class) return false;
if (this == other) return true;
if (this.id == null || other.id == null) return false;
return this.id.equals(other.id);

hashCode可以是 id.hashcode(),返回 0 31 (如果您喜欢) (或任何其他素数,在实践中不会有很大的不同)如果 ID 为null。

它代表一个用户

,在这种情况下,您可以 save> save()它们,并且他们还具有 id 表示与用户无关的无关备份存储系统的“实现细节”,您将比较所有内容 id - 任何2个用户对象的名称和电子邮件相等,是等于,即使对象碰巧表示2行(某种程度上 - 您对电子邮件都有唯一性约束。但是您仍然可以实现这一目标 - 制作一个尚未保存的新实例,直到直到您保存)。

但是那些彼此完全相反!

是的。他们是。烦人,不是吗?一个仅检查 id ,另一个检查除 ID 外的所有内容。

Hibernate/JPA对自己想要的想法感到困惑,既可以作为数据库抽象(第一个“拍摄”)以及一个对象持久框架(将其引导到第二种情况更近),因此我仍然没有' t实际上看到了这两种观点中的哪个是冬眠“首选”。

因此,嗯。我想选择一个。我认为第一个更加“正确”,并且更有可能做您想做的事情(请记住,击中每个属性可能会导致级别的选择以获取所有这些值,尤其是如果您具有相互联系的内容,即对于其他表来说,这是首先观点“更好”的几个原因之一),但是,根据我的经验,它不太常见。

如果您想选择第二个选项,则可以使用Lombok的东西。确保用 ID @equalsandhashcode.exclude 标记。对于第一个 - 更容易自己写,请参阅上面的摘要。

One rather crucial issue to consider is what a User object represents.

It represents a row in the database

That means if the unid is unset (i.e. you haven't save()d it yet) then no 2 user objects can be identical to each other. After all, if you make 2 instances of User, set every value (other than id which you don't mess with) to the same thing, and then save() both, you have 2 rows: Thus proving they aren't identical. However, to stick with java rules, they will be identical if there is reference identity (i.e. this == other).

When unid is set then the only thing that decides whether 2 User objects are identical, is if their unid is identical. All other properties are irrelevant - after all, if you query the same DB for the same row (getting a separate User instance for each, that have identical values), and then you setEmail on one of them, then the email field is no longer identical, but it doesn't matter: They refer to the same row, save one and the other changes along, thus, they are identical.

Conclusion: Write your own equals method that looks like:

if (other == null) return false;
if (other.getClass() != User.class) return false;
if (this == other) return true;
if (this.id == null || other.id == null) return false;
return this.id.equals(other.id);

And hashCode can just be id.hashCode(), returning 0 or 31 if you prefer (or any other prime, won't make much of a difference in practice) if id is null.

It represents a User

In that case, the fact that you can save() them, and that they also have an id representing absolutely nothing relevant about the user, just representing an 'implementation detail' of the backing storage system, you would compare everything except id - Any 2 User object whose name and email are equal, are equal, even if the objects happen to represent 2 separate rows (somehow - you have a uniqueness constraint on email. But you can still make that happen - make a new instance that you haven't saved yet, the SQLException won't occur until you save it).

But those are each others exact opposite!

Yeah. They are. Annoying, isn't it? One checks only id, the other checks everything except id.

Hibernate/JPA is confused about what it thinks it wants, peddling itself as both a database abstraction (the first 'take') as well as an object persistence framework (which steers much closer to the second case), and thus I still haven't actually seen which of these 2 views is 'preferred' by hibernate.

Hence, uh.. pick one, I guess. I think the first one is far more 'correct' and far more likely to do what you want (keep in mind that hitting every property might cause quite the cascade in selects to fetch all those values, especially if you have interconnected stuff, i.e. references to other tables, that's one of a few reasons why the first view is 'better'), however, in my experience, it's less commonly deployed.

If you want to choose the second option, you can just use lombok's stuff. Make sure to mark id with @EqualsAndHashCode.Exclude. For the first - easier to just write it yourself, see snippet above.

匿名。 2025-02-17 09:23:13

使用生成更少代码的选项,而无需第三方库。我更喜欢java7+。仅包括主要键字段,因为重要的是要验证两个不同的实例是否代表数据库中的同一行。无需验证所有字段值是否相同。

您可以阅读有关

Use the option that generates fewer code and no need 3rd party libraries. I prefer Java7+. Include just the primary key field because the important thing is to verify if 2 differents instances are representing the same row in database. There's no need to verify if all field values are the same.

You can read more about here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文