Hibernate: 如何覆盖映射超类中的属性

24

通用实体,超类:

@MappedSuperclass
public abstract class GenericEntity {
    private Integer id;
    public Integer getId() {return id;}
    public void setId(Integer id) {this.id = id;}
}

这个pojo:

@Entity
@Table(name = "POJO_ONE")
@SequenceGenerator(name = "HB_SEQ_POJO_ONE", sequenceName = "SEQ_POJO_ONE", allocationSize = 1)
public class PojoOne extends GenericEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "HB_SEQ_POJO_ONE")
    @Column(name = "ID")
    @AttributeOverride(name = "id", column = @Column(name = "ID"))
    private Integer id;

    @Override
    public Integer getId() {return id;}
}

我尝试使用这些注释:@AttributeOverride、@Id,但它们不起作用。你能帮我吗? 我想覆盖属性"id"以指定另一个列名和一个POJO/表的序列。 最好的方法是什么?


http://opensource.atlassian.com/projects/hibernate/browse/HHH-4380 - axtavt
2个回答

36

可以尝试这个

@MappedSuperclass
public abstract class GenericEntity {
    protected Integer id;
    ...

    public Integer getId() {return id;}
    public void setId(Integer id) {this.id = id;}
}


@Entity
@Table(name = "POJO_ONE")
@SequenceGenerator(name = "HB_SEQ_POJO_ONE", sequenceName = "SEQ_POJO_ONE", allocationSize = 1)
@AttributeOverride(name = "id", column = @Column(name = "ID"))
public class PojoOne extends GenericEntity {
    // we should not define id here again
    ...

    @Override
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "HB_SEQ_POJO_ONE")
    public Integer getId() {return id;}
}

使用这个解决方案时,当我尝试保存时,会出现以下异常:org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save() - BasicCoder
@user616564:我指的是两者都可以。但是,当然,这样做会破坏原本的目的,并允许您只使用不同的列名。恐怕,您可能不想这样做。 - Adeel Ansari
2
这里的答案 - https://dev59.com/bmoy5IYBdhLWcg3wZdCr 提供了我认为是稍微更好的方法,因为它复制的代码更少。 - sfitts
1
覆盖getter方法getId()不可能吗?在GenericEntity中,id是私有的,因此子类无法访问该属性。 - user2360507
1
@user2360507:已经修复了。谢谢。这个在原帖里就有,我想我是复制过来了。 - Adeel Ansari
显示剩余4条评论

4
为什么不在GenericEntity的id上注释@Id? 您还不应该重新定义id,而是将@AttributeOverride(name =“id”,column = @Column(name =“ID”))放在类上而不是字段上。 编辑: 我们在基类中使用它(package.OurTableGenerator是我们自己的实现):
@GeneratedValue ( generator = "ourTableGenerator", strategy = GenerationType.TABLE )
@GenericGenerator ( name = "ourTableGenerator", strategy = "package.OurTableGenerator",
  parameters = { @Parameter ( name = OurTableGenerator.TABLE_PARAM, value = "t_sequence" ),
                 @Parameter ( name = OurTableGenerator.SEGMENT_COLUMN_PARAM, value = "c_entity" ),
                 @Parameter ( name = OurTableGenerator.VALUE_COLUMN_PARAM, value = "c_nextHi" ),
                 @Parameter ( name = OurTableGenerator.INCREMENT_SIZE_COLUMN_PARAM, value = "c_blocksize" ) } )
@Id
@Column(name = "c_uid")
private Long uid;

这让我们能够为每个实体/表指定不同的块大小和序列。
对于您自己的表生成器,您可以继承org.hibernate.id.TableGenerator类。

我该如何为 ID 指定一个由表/实体确定的序列? - BasicCoder
如果您能发布OurTableGenerator类的源代码,那将是非常好的。 - Kiran Kumar
@KiranKumar 具体的代码取决于 Hibernate 版本,但基本上它是 org.hibernate.id.enhanced.TableGenerator 的子类和一些重写方法,特别是 configure(...)generate(...) 以及提供 SQL 字符串的方法。 - Thomas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接