Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.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 带有2个主键字段的JPA表_Java_Jpa_Orm_Jpa 2.0_Composite Key - Fatal编程技术网

Java 带有2个主键字段的JPA表

Java 带有2个主键字段的JPA表,java,jpa,orm,jpa-2.0,composite-key,Java,Jpa,Orm,Jpa 2.0,Composite Key,我有一个只包含2个字段的表。该表有一个由这两个字段组成的复合PK 当使用Netbeans从数据库创建实体bean时,实体bean不会像其他具有2个以上字段的表那样自动创建 所以我想我需要自己创建实体bean。创建这个实体bean的最佳实践是什么?它是否必须包含复合键对象?我不使用NetBeans,所以我不能真正谈论它的映射工具 对于映射复合键,有两个选项。你可以 用PK字段定义一个单独的对象,并在@Entity类中使用它 @Embeddable public class MyComposite

我有一个只包含2个字段的表。该表有一个由这两个字段组成的复合PK

当使用Netbeans从数据库创建实体bean时,实体bean不会像其他具有2个以上字段的表那样自动创建


所以我想我需要自己创建实体bean。创建这个实体bean的最佳实践是什么?它是否必须包含
复合键
对象?

我不使用NetBeans,所以我不能真正谈论它的映射工具

对于映射复合键,有两个选项。你可以

  • 用PK字段定义一个单独的对象,并在
    @Entity
    类中使用它

    @Embeddable
    public class MyCompositePK { 
        @Column
        private String fieldA;
        @Column
        private String fieldB;
    }
    @Entity 
    public class MyBean { 
        @EmbeddedId
        private MyCompositePK id;
        @Column
        private String fieldC;
    }
    
  • 使用PK字段定义一个未映射的POJO,并在
    @实体中使用它

    @Entity
    @IdClass(value=ClassAB.ClassABId.class)
    public class ClassAB implements Serializable {
        private String idA;
        private String idB;
    
        @Id
        @Column(name="ID_A")
        public String getIdA(){ return idA; }
        public void setIdA(String idA){ this.idA = idA; }
    
        @Id
        @Column(name="ID_B")
        public String getIdB(){ return idB; }
        public void setIdB(String idB){ this.idB = idB; }
    
        static class ClassABId implements Serializable {
            private String idA;
            private String idB;
    
            public String getIdA(){ return idA; }
            public void setIdA(String idA){ this.idA = idA; }
    
            public String getIdB(){ return idB; }
            public void setIdB(String idB){ this.idB = idB; }
    
            // implement equals(), hashcode()
        }
    }
    
    在本例中,
    ClassABId
    是一个静态的内部类,只是为了方便起见

Pascal Thivent对这个问题的出色回答中也解释了这些选项:

此相关问题讨论了这些方法之间的差异:。注意,字段的声明与
@IdClass
方法重复

无论如何,我认为除了创建两个类之外没有其他选择。这就是我问这个问题的原因:。这似乎有一个特定于hibernate的特性


作为一个旁注,如果您对DB结构有控制,您也可以考虑避免复合键。 谢谢@XaviLópez。您的解释修复了@Tom Anderson提到的声明为自己的IdClass的代码。当我声明它自己的IdClass有2个@Id列时,获取该实体列表的JPA查询返回结果列表中预期的“n”项,但该列表中的每个项都为null。但预计尺寸为“n”。在更改为静态内部类(重构较少)后,它能够返回正确的结果集


根据我的说法:自引用IdClass不起作用,因为自引用已经是一个实体,需要在持久性上下文中。如果我还有一个相同类型的主键对象,那么持久性上下文中将有两个“相同”的对象。因此,这是不允许的。因此,我们不应该使用自引用@IdClass。创建一个静态的内部类作为主键类型,这种主键类型侵入性较小。

@Xavi López:它们一起构成PK。鉴于对象只包含两个主键字段,它是否可以是自己的
IdClass
?@TomAnderson,这很有趣。我从来没有试过。看来,没有成功。规范似乎没有对此做出任何规定。可能取决于实现。@TomAnderson:我不这么认为,因为ID类必须仅基于复合键值实现其equals()方法。