【问题标题】:Hibernate - How to use a generator to create a primary key for a reference table?Hibernate - 如何使用生成器为引用表创建主键?
【发布时间】:2014-10-06 20:20:07
【问题描述】:

我正在努力让 Hibernate(使用 MySQL)从“主表”生成参考表的主键。我的问题是我有一个有 2500 万行的大表,现在我需要添加多个额外的列,因为将来会添加更多列,我选择使用引用表的方式而不是添加列主表(重建需要几个小时...... :)

所以有一个主表和一个参考表。在我的概念中,参考表的主键应该由主表的主键生成。我可以先insert 进入主表,然后select 将其主键用于insert 进入参考表,但这对我来说似乎不是最好的方法。所以我想用 Hiibernate 的generators,但是我不知道怎么用。

这是主表:

@Entity 
@Table
public class Task {

    @Id
    @GeneratedValue
    @Column()
    private Integer id;

    // ...

    @OneToOne(mappedBy = "task_ref", orphanRemoval=true, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private Stuff stuff;

    // ...
}

以及参考表:

@Entity
@Table
public class Stuff {

    @Id
    @Column(name = "stuff_id")
    @GeneratedValue()
    private Integer stuff_id;

    // ...

    @OneToOne(orphanRemoval=true, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    private Task task_ref;

    // ...
}

那么.. 我如何使用生成器从表 Task 的主键创建表 Stuff 的主键?

非常欢迎任何建议或其他解决方案!

谢谢!

【问题讨论】:

  • 从您的代码看来,您正在做的是为每个类创建一个 PK 对吗?但是根据您的解释,您想将其中一个类的 ID (Pk) 作为另一个类的 ID (PK) 的一部分,对吗?我不确定你想通过解释来完成什么,你能澄清一下吗?
  • @AngelVillalain 对不起,代码令人困惑。我的意思是 PK Stuff.stuff_id 应该从主表(Task.id)的相应 PK 生成,因此它们应该相等,我可以对它们进行 JOIN。
  • Stuff 是不是类似于Task 的子类?
  • 您还可以添加有关架构如何的信息,以防您无法更改架构,以便我有更好的画面。

标签: java mysql hibernate jpa orm


【解决方案1】:

您可以使用 Task 对象作为您的 id,例如,请参阅 EmbeddedIdIdClass。如果Stuff 表示您的域模型中Task 实体的子类,您应该对该实体进行建模,其中您必须将Stuff 实体表示为Joined SubclassTask 实体.在这两种情况下,都不再需要 Stuff 实体中的额外 Id

【讨论】:

  • 啊,我明白了。两者都是单独的类,重写不是一种选择:/
  • 如果您不消除额外的id 属性,则配置为使用EmbeddedIdIdClass 不会影响您的数据库架构。而如果你不想换班,那么IdClass是你最好的选择。请参阅以下answer 了解更多信息。
【解决方案2】:

这是您应该如何将双向 OneToOne 关联与共享主键映射:

@Entity 
@Table
public class Task {

    @Id
    @GeneratedValue
    private Integer id;

    // ...

    @OneToOne(mappedBy = "task_ref", orphanRemoval=true, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private Stuff stuff;

// ...
}

@Entity
@Table
public class Stuff {

    @Id
    @Column(name = "stuff_id")
    private Integer stuff_id;

    // ...

    @OneToOne(fetch = FetchType.LAZY)        
    @MapsId 
    @JoinColumn(name = "stuff_id") 
    private Task task_ref;

    // ...
}
  1. 只有父级需要级联到子级实体,反之则不需要。
  2. Parent 仅具有关联的“逆”端。
  3. 共享主键在子实体中既是主键又是外键
  4. MapsId 注释允许您共享 @Id 和 OneToOne 关联的主键

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多