首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在用户名或用户电子邮件等属性下使用@Id注释是一种好的做法吗

在用户名或用户电子邮件等属性下使用@Id注释是一种好的做法吗
EN

Stack Overflow用户
提问于 2018-08-26 20:57:04
回答 2查看 171关注 0票数 1

例如,当您为除id之外的文件设置@Id属性时,可能会发生什么复杂情况?

代码语言:javascript
运行
复制
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="user_id")
private Integer user_id;

@Id
@Size(min=6,message="email is too short")
@Pattern(regexp = "^.+@.+\\..+$",message="invalid email")
@Column(name="user_email")
private String user_email;

在我的user pojo类中:如果我没有为user_id定义id注解,而是为user_email定义id注解,那么从长远来看,这会产生任何复杂的情况吗?

EN

回答 2

Stack Overflow用户

发布于 2018-09-04 06:12:21

这是一种糟糕的做法。

电子邮件可能会改变,但主键(这是@Id注释的内容)永远不应该改变。用户名也可能会改变,比如在这个网站上。

票数 0
EN

Stack Overflow用户

发布于 2018-09-04 07:28:45

首先让我说:这是一个很好的问题!对此的简短回答是:

No,使用@Id注释user_emailusername等字段不是一种好的做法。

为了更深入地了解为什么,让我们首先记住主键(PK)是如何定义的。在大多数面向SQL的数据库系统中,PK definition至少遵循两个假设,在这两个假设下,PK始终为:

  • (i)不为空的
  • (Ii)唯一的

与您的想法/问题相关的含义:

  • (a):

在可以将User实例持久化到数据库之前,应该已经将usernameuser_email值设置为该实例。在这种情况下,它丢失了,或者只有在稍后的时间点才能知道:持久性=不可能。反之亦然,它永远不会被设置为未知值,也就是null,例如,如果用户根本不能提供他/她的电子邮件地址(即使2018年很少)。

  • (B):

在大多数应用程序中,username/user_email的实际值往往是唯一的。然而,在应用程序的业务逻辑中,您必须确保其他用户不会两次输入已经存在/已知的username/user_email。如果您对持久性进行了注释,那么再次声明:@Id = If。不过,最有可能的情况是,允许这些字段中的一个字段存在重复项将以任何方式违反其语义。

如果您将user_id注释为@Id字段:在两种情况下都没有问题。

在ORM上下文中,the JPA specification document扩展了这个定义,并在第31页说明:

其主键的值唯一地标识持久化上下文中的实体实例和EntityManager操作,如第3章“实体操作”中所述。应用程序不得更改主键的值。如果发生这种情况,行为是未定义的。

这就产生了下一个含义

  • (c)

根据定义,您不允许以编程方式/在运行时更改@Id字段的值。这些字段的控制应该保持在实现JPA specification.的对象关系映射器的一侧

正如在回答中指出的那样,usernameuser_email可能会在应用程序的生命周期中发生变化。原因:从应用程序用户的角度来看,数据是不稳定的。用户可能想要更改这些属性(在未来的某个时间),例如,如果他们结婚或更改他们的电子邮件提供商。

但是,通常可以注释类型为String (和其他类型)的字段,请参见第31页:

简单主键或复合主键的字段或属性应该是以下类型之一:任何Java primitive type;任何原始包装类型;java.lang.Stringjava.util.Datejava.sql.Datejava.math.BigDecimaljava.math.BigInteger

因此,人们可能会忍不住说:好吧,我们就这么做吧!然而,人们应该后退一步,反思(a)域或(b)应用程序的预期用例对预期应用程序的数据库模式施加的内容。如上所述,这在您的场景中尤其重要。

考虑到这些“现实世界”的考虑因素,您最好只将@Id注释为代理键,如示例中的user_id。这一点在数据库的整个生命周期内都不会改变。问:为什么它不会改变?答:没有实际的理由来满足应用程序用户定义的业务案例。

希望这能有所帮助。

角度提示

最好从一开始就使用Long而不是Integer;这样,在您作为软件开发人员的有生之年(对于99.5%以上的应用程序是正确的),您将拥有足够的主键值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52026469

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档