Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将复合PK的一部分映射到复合FK_Java_Hibernate_Hibernate Mapping - Fatal编程技术网

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

Java 将复合PK的一部分映射到复合FK,java,hibernate,hibernate-mapping,Java,Hibernate,Hibernate Mapping,我的数据模型由具有历史记录的项组成。我会立即调用一个时间点;因此,所有表都有一个instant_id,用于指定在该瞬间如何配置该项。即时_id被卷到所有表的复合主键中。想象一下下面的例子: Table Computer ============ PK int instant_id <-- Shared id PK int computer_id <-- Child id int computer_type_id <-- Parent id

我的数据模型由具有历史记录的项组成。我会立即调用一个时间点;因此,所有表都有一个instant_id,用于指定在该瞬间如何配置该项。即时_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
然后:


无论我如何将MapsId与JoinColumns结合起来,我似乎都无法实现这一点。有什么想法吗?

我看不到一个多人协会。您没有向我们展示ComputerType是如何声明的,我假设它是一个实体。如果是这种情况,根据您提供的表定义,Computer和ComputerType共享一个复合主键:instant_id和Computer_type_id


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

我想我现在理解了这个问题。你还需要把计算机的Type Type ID看作是计算机表的复合键的一部分。列computer\u type\u id本身没有太大意义;在ComputerType表中,它是主键的一部分,另一部分是instant\u id。因此,如果是这种情况,您也需要将其作为Computer表的主键的一部分,因为您永远不会有Computer.instant\u id=ComputerType.instant\u id和Computer.Computer\u类型\u id ComputerType.Computer\u类型\u 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
}

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


希望这有帮助。

好例子我不认为这是同样的问题。这是一个多模式。我的有很多。此外,答案中没有复合主键。我仅使用“Computer”和“ComputerType”作为示例。。。假设两个表都没有“instant_id”列。那么我认为多通映射是清楚的。现在想象一下,计算机和计算机类型可能会随着时间的推移而变化,我们需要保存它们在特定时间的历史记录。我们用“即时id”标记时间。多通关联仍然存在,但键很难在hibernate中使用。哎呀,我刚刚意识到我对“ComputerId”的定义有点错误。它应该包含即时id和计算机id,而不是计算机类型id。它现在已修复。
Computer {
   @EmbeddedId ComputerId id;

   @MapsId('instant_id')
   @ManyToOne
   @JoinColumns({
       @JoinColumn(name='instant_id',...),
       @JoinColumn(name='computer_type_id',...)
   })
   ComputerType computerType;
}
@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
}