Java堂  


JPA和Hibernate注解的继承问题

归档在: JavaPlateform, Web&Server — Jet @ 3:03 下午
Tags: ,
原文出处: http://www.javatang.com/archives/2008/06/19/0308269.html
作者: Jet Mah from Java堂
声明: 可以非商业性任意转载, 转载时请务必以超链接形式标明文章原始出处、作者信息及此声明!

UUID类型的主键字段是长度为32的字符类型,Hibernate中自带自动生成UUID类型的主键,但有的时候需要自定义长32的字符串最为主键值,因此这里就有了一个分类关系:系统自带的UUID和用户自定义的UUID都有一个共性,都是一个长32的字符。我们基于此创建一个继承体系。

  1. // UUIDBase.java
  2. @MappedSuperclass
  3. public abstract class UUIDBase {
  4.  
  5.     protected String id;
  6.  
  7.     @Id
  8.     @Column(nullable=false, updatable=false, length=32)
  9.     public String getId() {
  10.         return id;
  11.     }
  12.  
  13.     public void setId(String id) {
  14.         this.id = id;
  15.     }
  16. }
  1. // UUIDSystem.java
  2. @MappedSuperclass
  3. public abstract class UUIDSystem extends UUIDBase {
  4.     @Override
  5.     @GeneratedValue(generator="system-uuid")
  6.     @GenericGenerator(name="system-uuid", strategy="uuid")
  7.     public String getId() {
  8.         return id;
  9.     }
  10. }
  1. // UUIDCustom.java
  2. @MappedSuperclass
  3. public abstract class UUIDCustom extends UUIDBase {
  4.     @Override
  5.     @GeneratedValue(generator="custom-uuid")
  6.     @GenericGenerator(name="custom-uuid", strategy="package.IDGenerator")
  7.     public String getId() {
  8.         return id;
  9.     }
  10. }
  1. // POJO.java
  2. @Entity
  3. public class POJO extends UUIDCustom {
  4.     //...
  5. }

但是如果这样做的话如果对POJO进行操作的时候,会出现如下的异常:
org.hibernate.MappingException: Repeated column in mapping for entity

如果将UUIDBase修改如下:

  1. // UUIDBase.java
  2. @MappedSuperclass
  3. public abstract class UUIDBase {
  4.  
  5.     protected String id;
  6.  
  7.     @Id
  8.     @Column(nullable=false, updatable=false, length=32)
  9.     @GeneratedValue(generator="system-uuid")
  10.     @GenericGenerator(name="system-uuid", strategy="uuid")
  11.     public String getId() {
  12.         return id;
  13.     }
  14.  
  15.     public void setId(String id) {
  16.         this.id = id;
  17.     }
  18. }

这个时候无论子类中getId()方法使用什么注解都是无效的,最终主键还是按照父类的主键生成器。

为了避免出现这样的错误,建议将主键的注解一步到位,不要使用继承扩展的方式。