[译文]JPA的实施模式:使用UUID作为主键

原文:JPA implementation patterns: Using UUIDs as primary keys

作者:Albert Sikkema

出处:http://blog.xebia.com/2009/06/03/jpa-implementation-patterns-using-uuids-as-primary-keys/

 

作为Vincent Partington的关于JPA实施模式的博客序列的继续,我想补充以下内容。

 

JPA缺省的主键方式是使用带有strategy属性的@GenerateValue注解来把主键策略设置为AUTOIDENTITYSEQUENCE或者TABLE中的一个,你结合自己的具体情况来挑选最适合的策略,仅此而已。

不过也可以选择由你自己来生成主键。

使用UUID做主键是理想的,而且有一些很大的好处。在我们当前的项目中,我们通过创建一个抽象的基类来使用这一策略,其负责处理主键,我们的实体会继承这一基类。

 

@MappedSuperclass

public abstract class AbstractBaseEntity implements Serializable {

         private static final long serialVersionUID = 1L;

 

         @Id

         private String id;

 

         public AbstractBaseEntity() {

                  this.id = UUID.randomUUID().toString();

         }

 

         @Override

         public int hashCode() {

                  return id.hashCode();

         }

 

         @Override

         public boolean equals(Object obj) {

                  if (this == obj)

                            return true;

                  if (obj == null)

                            return false;

                  if (!(obj instanceof AbstractBaseEntity)) {

                            return false;

                  }

                  AbstractBaseEntity other = (AbstractBaseEntity) obj;

                  return getId().equals(other.getId());

         }

}

 

总的来说使用UUID和序列(sequence)的比较在网络上已经被广泛地讨论,因此在这里我不会说得过于详细,尽管如此,在这里还是给出一些优缺点:

 

优点

 

Ÿ           一旦编写了这样的一个基类之后,每个实体就都能够无偿地获得一个Id,如果像前面的例子那样实现了equalshashCode方法的话,你还可以把这作为额外的收获添加进来。

Ÿ           UUID是全球唯一(Universal Unique,这是UUID这一名称的含义)的,这意味着如果你需要无需重新生成键而拷贝/合并位置a到位置b的记录的话,那么你拥有着极大的灵活性。

Ÿ           UUID是不可推测的,这意味着把它们暴露到允许告知URL的那些地方是可以变得更加安全的,不过这是否是一种好的做法则属另一回事。

 

缺点

 

Ÿ           性能可能会是个问题,参见http://johannburkard.de/blog/programming/java/Java-UUID-generators-compared.html,一些数据库在使用UUID(至少在它们被存储成串时)进行索引时表现欠佳。

Ÿ           排序、分类,这方面不言自明。

Ÿ           JPA特有的:不能通过检查Id域是否被设定来测试记录是否已被持久。可能有人会质疑是否总是会需要这样的检查。

 

结论

 

UUID易于使用,不过,如果开放JPA规范,把UUID作为一种策略包括进来不是很好吗?有些JPA的实现,比如Hibernate,就已经支持了这样的做法:

 

@Id @GeneratedValue(generator="system-uuid")

@GenericGenerator(name="system-uuid",

  strategy = "uuid")

 

你可能感兴趣的:(Hibernate,jpa,Blog)