Java 带有2个主键字段的JPA表
我有一个只包含2个字段的表。该表有一个由这两个字段组成的复合PK 当使用Netbeans从数据库创建实体bean时,实体bean不会像其他具有2个以上字段的表那样自动创建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
所以我想我需要自己创建实体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
@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()方法。