当前位置: 首页 > 知识库问答 >
问题:

来自具有属性访问的外键的JPA复合主键

贲宜春
2023-03-14

问题

如果我像下面的例子一样使用属性访问类型,我是否也必须为引用的FK定义getter和setter?

我不认为是这样,但Java EE6的官方文档是这样做的。

    null
Example 7-2 Embeddable Composite Primary Key Class

@Embeddable
public class EmployeePK implements Serializable {
    private String name;
    private long id;

    public EmployeePK() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public int hashCode() {
        return (int) name.hashCode() + id;
    }

    public boolean equals(Object obj) {
        if (obj == this) return true;
        if (!(obj instanceof EmployeePK)) return false;
        if (obj == null) return false;
        EmployeePK pk = (EmployeePK) obj;
        return pk.id == id && pk.name.equals(name);
    }
}

Example 7-3 JPA Entity With an Embedded Composite Primary Key Class

@Entity
@Access(AccessType.PROPERTY)
public class Employee implements Serializable {
    EmployeePK primaryKey;
 
    public Employee() {
    }
 
    @EmbeddedId
    public EmployeePK getPrimaryKey() {
        return primaryKey;
    }
 
    public void setPrimaryKey(EmployeePK pk) {
        primaryKey = pk;
    }
 
    @ManyToOne
    @MapsId("id")
    private classWithPKid fkobject1;

    @ManyToOne
    @MapsId("name")
    private classWithPKname fkobject2;
    ...
}

共有1个答案

武嘉祥
2023-03-14

当Access(PROPERTY)应用于实体类、映射超类或可嵌入类时,映射注释可以放置在该类的属性上,持久化提供程序运行时通过该类定义的属性访问持久化状态。所有未使用瞬态批注进行批注的属性都是持久性的。当Access(PROPERTY)应用于这样的类时,可以有选择地在类中指定单独的属性,例如变量Access。若要指定持久化实例变量供持久化提供程序运行时访问,必须将该实例变量指定为access(字段)。如果映射注释放置在未为其指定Access(FIELD)的类定义的任何实例变量上,则该行为是未定义的。从超类继承的持久状态根据这些超类的访问类型进行访问。

可嵌入类的访问类型由其嵌入的实体类、映射超类或可嵌入类(包括作为元素集合的成员)的访问类型确定,而与包含类的访问类型是显式指定的还是默认的无关。可以通过如上所述的访问注释为该可嵌入类指定用于该可嵌入类的不同访问类型。

当AccessType被设置为实体类的PROPERTY时,提供程序将使用这些方法来获取持久状态和映射数据。当类的AccessType是property时,持久性提供程序没有义务在字段上查找映射注释。另外,请注意AccessType是由嵌入类继承的,这就是EmployeePK也需要定义getter/setter的原因。根据规范中的说明,当实体类使用Access(PROPERTY)时,您应该执行以下操作之一:

>

  • 为FK字段定义getter/setter方法,并将映射放在getter方法上

    示例:

    @Entity
    @Access(AccessType.PROPERTY)
    public class Employee {
        private EmployeePK primaryKey;
    
        private ClassWithPKid fkobject1;
    
        @EmbeddedId
        public EmployeePK getPrimaryKey() {
            return primaryKey;
        }
    
        @ManyToOne
        @MapsId("id")
        public ClassWithPKid getFkobject1() {
            return fkobject1;
        }
    }
    

    或者,在持久字段上显式定义Access(字段)

    示例

    @Entity
    @Access(AccessType.PROPERTY)
    public class Employee {
        private EmployeePK primaryKey;
    
        @ManyToOne
        @MapsId("id")
        @Access(AccessType.FIELD)
        private ClassWithPKid fkobject1;
    
        @EmbeddedId
        public EmployeePK getPrimaryKey() {
            return primaryKey;
        }
    }
    

  •  类似资料:
    • 我有一个实体,它的复合主键由两个字段组成,其中一个也是复合外键的一部分。 背景:我有实体<代码>人员 、<代码>区域 和<代码>会话 。 与具有多对多关系,使用称为“和实体。 所以,我有,主键为(,)。本身是的外键。 也有一个字段。我希望(,)是的复合外键。 我的PersonSession代码: } 这看起来不错,它在数据库中创建了所有正确的关系。当我尝试插入个性化会话对象时,问题就出现了——ar

    • 我在oracle数据库中有一个包含客户数据的表。以下是一个简化的定义: 此表的主键是。 该表有许多行,其中为空。在数据库级别,没有问题,但是当我试图通过JPA实体访问这些行时,会导致一些问题: 1:使用

    • 我有以下表格,如何将它们映射到JPA实体: 事件表与会议表具有一对多的关系。我如何在JPA中映射这种双向关系?

    • EmbeddedId或IdClass注释用于表示复合主键。如何在没有(EmbeddedId或IdClass)的情况下使用复合主键? 如果可以在没有(EmbeddedId或IdClass)的情况下使用复合主键,那么如何使用EntityManager.find(Entity Class,Object primaryKey)方法在复合主键(Multiple primaryKey)的情况下查找实体(因为没

    • 问题内容: 我在oracle的1个表中有一个复合主键。我想为第二个表中的一个表项创建一个外键,该表项引用第一个表中的复合主键。我收到错误ORA-02256。关于如何输入此内容有任何想法吗? 问题答案: 该错误是因为FOREIGN KEY是一列,但是您尝试提供两列作为父列。不需要绑定到复合键,因为它没有列… 您也有倒退的关系-使用: 我将为要来自的任何表添加一个外键约束。

    • 我正在构建一个数据库的模式。我有下面两张表。。。 我想创建一个名为hasTool的表,它使用外键约束具有两个表的主键。然而,除此之外,我还想使这两个字段都成为新表hasTool的复合键。我尝试了以下方法,但似乎没有产生预期的行为: 我想允许表允许多个实例的userID或工具ID,但不是两者,并表用户和工具上的现有值。 提前谢谢!