代码之家  ›  专栏  ›  技术社区  ›  drekka

使用hibernate/jpa注释映射多字段主键的问题

  •  0
  • drekka  · 技术社区  · 14 年前

    我被一个使用多字段主键的数据库困住了。在这种情况下,我有一个主表和明细表,其中明细表的主键包含字段,这些字段也是外键的主表。这样地:

    Master primary key fields:
        master_pk_1
    
    Details primary key fields:
        master_pk_1
        details_pk_2
        details_pk_3
    

    在master类中,我们这样定义hibernate/jpa注释:

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idGenerator")
    @Column(name = "master_pk_1")
    private long masterPk1;
    
    @OneToMany(cascade=CascadeType.ALL)
    @JoinColumn(name = "master_pk_1", referencedColumnName = "master_pk_1")
    private List<Details> details = new ArrayList<Details>();
    

    在details类中,我定义了id和back引用,如下所示:

    @EmbeddedId
    @AttributeOverrides( { 
            @AttributeOverride( name = "masterPk1", column = @Column(name = "master_pk_1")),
            @AttributeOverride(name = "detailsPk2", column = @Column(name = "details_pk_2")),
            @AttributeOverride(name = "detailsPk2", column = @Column(name = "details_pk_2")) })
    private DetailsPrimaryKey detailsPrimaryKey = new DetailsPrimaryKey();
    
    @ManyToOne
    @JoinColumn(name = "master_pk_1", referencedColumnName = "master_pk_1", insertable=false)
    private Master master;
    

    所有这些的目标是我可以创建一个新的主控形状,向它添加一些细节,当保存时,jpa/hibernate将在masterpk1字段中为master生成新的ID,并自动将其传递给细节记录,将其存储在detailsprimarykey类中匹配的masterpk1字段中。至少这就是我所看到的文档所暗示的。

    实际上,Hibernate似乎核心地创建和更新了数据库中的记录,但没有将键传递给内存中的细节类。相反,我必须自己手动设置它。

    我也发现没有 insertable=true 添加到master的后引用中,hibernate将创建SQL,其中在insert语句中两次列出master_pk_1字段,导致数据库引发异常。

    我的问题很简单,注释的排列是否正确?还是有更好的方法?

    2 回复  |  直到 12 年前
        1
  •  2
  •   Thierry    14 年前

    你也可以添加详细的PrimaryKey映射吗?

    在您的映射中,奇怪的是您映射的是细节故事中的“master-pk-1”列的两倍。通过添加insertable=false选项,现在可以插入Works,但我想更新仍然不起作用(事实上,当您在一个实体中多次映射列时,必须用insertable=false、uptable=false注释除其中一列之外的所有列)

    要纠正这个问题,我认为您应该将@manytoone主控形状移动到细节ID(删除insertable=false选项)。

    您还应该将mappedby=“detailsPrimaryKey.master”选项添加到@onetomany注释中,如果希望自动保存子级,还可以添加一个级联。

    (看 http://beavercreekconsulting.com/blog/2008/10/hibernate-annotations-for-a-one-to-many-mapping/ 您将看到一个代码解决与您的问题非常相似的问题)

        2
  •  0
  •   Kiarash Zamanifar    12 年前

    我也有同样的问题。起初我想使用@primarykeyjoincolumn,但并非所有详细信息的列都是外键。所以我将使用@joincolumn。但正如您所说,JPA实现没有选择分配 自动生成的主键 在向数据库写入数据时,参考了序列表。我认为这是浪费密钥,可能会导致并发/同步问题,以便从数据库中获取可能最终不会提交给DB的实体的ID。