将复合PK的一部分映射到复合FK

时间:2015-03-16 17:45:44

标签: java hibernate hibernate-mapping

我的数据模型由具有历史记录的项目组成。我会及时拨打一个"瞬间&#34 ;;因此,所有表格都有一个" instant_id"指定该项目在该时刻的配置方式。 " instant_id"被转换为所有表的复合主键。想象一下以下示例:

Table Computer
============
PK int       instant_id    <-- Shared id
PK int       computer_id   <-- Child id
int computer_type_id    <-- Parent id
varchar      foo

Table ComputerType
==================
PK int  instant_id      <--   Shared id
PK int  computer_type_id   <--  Parent id
varchar bar

ComputerType主键的计算机映射(instant_id,computer_type_id)中有一个外键。

我们使用像

这样的东西
@Embeddable ComputerId {
   @Column(name='instant_id', nullable=false) int instant_id,
   @Column(name='computer_id', nullable=false) int computer_id
}

然后:

Computer {
   @EmbeddedId ComputerId id;

   @MapsId('instant_id')
   @ManyToOne
   @JoinColumns({
       @JoinColumn(name='instant_id',...),
       @JoinColumn(name='computer_type_id',...)
   })
   ComputerType computerType;
}

无论我如何将MapsId与JoinColumns结合使用,我似乎无法将其发挥作用。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

我没有看到ManyToOne关联。您没有向我们展示如何声明 ComputerType ,我假设它是一个实体。如果是这种情况,根据您提供的表格定义,计算机 ComputerType 共享复合主键: instant_id computer_type_id

如果这是真的并且它们共享相同的主键,那么最好将这两个表标准化为一个表。

答案 1 :(得分:0)

我想我现在明白了这个问题。您还需要将computer_type_id视为Computer表的组合键的一部分。列computer_type_id本身并不是很有意义;在ComputerType表中,它是主键的一部分,另一部分是instant_id。因此,如果是这种情况,您还需要将其作为计算机表主键的一部分包含在内,因为您永远不会遇到Computer.instant_id = ComputerType.instant_id AND Computer.computer_type_id&lt;&gt;的情况。 ComputerType.computer_type_id,用于给定的相关关联。 (如果我理解这个案子的话)

如果您同意,那么这就是解决方案:

@Embeddable
public class ComputerId implements Serializable {
    int computer_id;

    @ManyToOne
    @JoinColumns({@JoinColumn(name = "instant_id", insertable=false, updatable=false), 
        @JoinColumn(name = "computer_type_id", insertable=false, updatable=false) })
    ComputerType computerType;
    // getters and setters
}

@Entity
public class Computer {
    @EmbeddedId
    ComputerId computerId;
    // getters and setters
}

public class ComputerTypeId implements Serializable {
       @Column(name="instant_id", nullable=false) int instant_id;
       @Column(name="computer_type_id", nullable=false) int computer_type_id;
       // getters and setters
}

@Entity
public class ComputerType {
    @EmbeddedId
    ComputerTypeId computerTypeId;
    String bar;
    // getters and setters
}

最后,您可能需要考虑Hibernate Envers进行实体版本控制。

希望这有帮助。