【问题标题】:How do I override the GenerationType strategy using Hibernate/JPA annotations?如何使用 Hibernate/JPA 注释覆盖 GenerationType 策略?
【发布时间】:2012-04-06 23:51:33
【问题描述】:

我正在考虑使用 Annotations 来定义我的 Hibernate 映射,但遇到了一个问题:我想使用基实体类来定义公共字段(包括 ID 字段)但我希望不同的表具有不同的 ID 生成策略:

@MappedSuperclass
public abstract class Base implements Serializable {
    @Id
    @Column(name="ID", nullable = false)
    private Integer id;
    public Integer getId(){return id;}
    public void setId(Integer id){this.id = id;}
    ...
}

@Entity
@Table(name="TABLE_A")
public class TableA extends Base {
    // Table_A wants to set an application-defined value for ID
    ...
}

@Entity
@Table(name="TABLE_B")
public class TableB extends Base {
    // How do I specify @GeneratedValue(strategy = AUTO) for ID here?
    ...
}

有没有办法做到这一点?我尝试在TableB 中包含以下内容,但hibernate 反对我两次使用同一列,这似乎是错误的:

@Override // So that we can set Generated strategy
@Id
@GeneratedValue(strategy = AUTO)
public Integer getId() {
    return super.getId();
}

【问题讨论】:

    标签: java hibernate jpa annotations


    【解决方案1】:

    在上面的代码中,您似乎在字段(超类)和方法(子类)上混合了注释。 Hibernate reference documentation 建议避免这种情况,我怀疑它可能会导致问题。根据我使用 Hibernate 的经验,注释 getter/setter 方法而不是字段更安全、更灵活,所以如果可以的话,我建议坚持这种设计。

    作为您的问题的解决方案,我建议从您的 Base 超类中完全删除 id 字段。相反,将该字段移动到子类中,并在您的基类中创建抽象 getId()setId() 方法。然后在您的子类中覆盖/实现 getId()setId() 方法,并使用所需的生成策略注释 getter。

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      在子方法中不要添加第二个@Id 标签。

      @Override // So that we can set Generated strategy
      @GeneratedValue(strategy = AUTO)
      public Integer getId() {
          return super.getId();
      }
      

      【讨论】:

        【解决方案3】:

        我的决心:

        Base 类重构为:

        @MappedSuperclass
        abstract class SuperBase<K> {
            public abstract K getId();
        }
        
        @MappedSuperclass
        class Base<K> extends SuperBase<K> {
            @Id @GeneratedValue(AUTO)
            public K getId() { ... }
        }
        

        然后,您可以从 Base 扩展大多数实体类,如果需要覆盖 @GeneratedValue,只需从 SuperBase 扩展并定义它。

        【讨论】:

          【解决方案4】:

          如果你把你的注解放在getter而不是字段上,当你在子类中重写方法时,放置在那里的注解将被使用而不是超类中的注解。

          【讨论】:

            猜你喜欢
            • 2011-04-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多