英文:
What is foreignKey and inverseForeignKey in @JoinTable annotation?
问题
以下是您提供的代码的翻译部分:
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
@EqualsAndHashCode
@ToString(callSuper = true)
@IdClass(QuarantinePolicyIdentity.class)
@Entity(name = PolicyServiceConstants.QUARANTINE_POLICY_TABLE)
@Table(uniqueConstraints = @UniqueConstraint(name = PolicyServiceConstants.QUARANTINE_POLICY_UNIQUE_NAME_CONSTRAINT,
columnNames = {"customerUuid", "name"}),
indexes = {@Index(name = PolicyServiceConstants.QUARANTINE_POLICY_UNIQUE_INDEX,
columnList = "orderNo",
unique = false)
})
public class QuarantinePolicyEntity {
@Id
private String quarantinePolicyId;
@Id
@JsonIgnore
private String customerUuid;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinTable(name = PolicyServiceConstants.QUARANTINE_POLICY_OUTBOUND_RULE_TABLE,
foreignKey = @ForeignKey(name = PolicyServiceConstants.FOREIGN_KEY_QUARANTINE_POLICY_QPOR),
inverseForeignKey = @ForeignKey(name = PolicyServiceConstants.FOREIGN_KEY_QUARANTINE_POLICY_ORQP))
private Set<RuleEntity> outboundRules;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinTable(name = PolicyServiceConstants.QUARANTINE_POLICY_INBOUND_RULE_TABLE,
foreignKey = @ForeignKey(name = PolicyServiceConstants.FOREIGN_KEY_QUARANTINE_POLICY_QPIR),
inverseForeignKey = @ForeignKey(name = PolicyServiceConstants.FOREIGN_KEY_QUARANTINE_POLICY_IRQP))
private Set<RuleEntity> inboundRules;
private String createdBy;
private Date createdDate;
private String lastModifiedBy;
private Date lastModifiedDate;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof QuarantinePolicyEntity)) return false;
QuarantinePolicyEntity that = (QuarantinePolicyEntity) o;
return com.google.common.base.Objects.equal(getQuarantinePolicyId(), that.getQuarantinePolicyId()) &&
com.google.common.base.Objects.equal(getCustomerUuid(), that.getCustomerUuid());
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), quarantinePolicyId, customerUuid);
}
}
请注意,这是您提供的代码的简单翻译,其中的注解和变量名等保持不变。对于您提到的问题:
-
@JoinTable
注解用于指定连接两个实体之间关系的中间表信息。foreignKey
和inverseForeignKey
是用来指定外键的约束的,分别用于指定在中间表中哪个外键引用哪个实体。在这种情况下,它们是通过注解中的name
属性引用外键约束的名字,这些约束应该在其他地方定义。 -
关于如何指定外键和关联表的问题,
@JoinTable
注解中的foreignKey
和inverseForeignKey
通过引用外键约束的名字来实现。外键约束的名字应该在其他地方定义,通常是在实体类之外的地方,可能是在数据库迁移脚本或配置文件中。
请注意,这只是代码的简单翻译,某些上下文可能会影响更详细的解释。
英文:
I am having a project where I found, a schema something like this
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
@EqualsAndHashCode
@ToString(callSuper = true)
@IdClass(QuarantinePolicyIdentity.class)
@Entity(name = PolicyServiceConstants.QUARANTINE_POLICY_TABLE)
@Table(uniqueConstraints = @UniqueConstraint(name = PolicyServiceConstants.QUARANTINE_POLICY_UNIQUE_NAME_CONSTRAINT,
columnNames = {"customerUuid", "name"}),
indexes = {@Index(name = PolicyServiceConstants.QUARANTINE_POLICY_UNIQUE_INDEX,
columnList = "orderNo",
unique = false)
})
public class QuarantinePolicyEntity {
@Id
private String quarantinePolicyId;
@Id
@JsonIgnore
private String customerUuid;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinTable(name = PolicyServiceConstants.QUARANTINE_POLICY_OUTBOUND_RULE_TABLE,
foreignKey = @ForeignKey(name = PolicyServiceConstants.FOREIGN_KEY_QUARANTINE_POLICY_QPOR),
inverseForeignKey = @ForeignKey(name = PolicyServiceConstants.FOREIGN_KEY_QUARANTINE_POLICY_ORQP))
private Set<RuleEntity> outboundRules;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinTable(name = PolicyServiceConstants.QUARANTINE_POLICY_INBOUND_RULE_TABLE,
foreignKey = @ForeignKey(name = PolicyServiceConstants.FOREIGN_KEY_QUARANTINE_POLICY_QPIR),
inverseForeignKey = @ForeignKey(name = PolicyServiceConstants.FOREIGN_KEY_QUARANTINE_POLICY_IRQP))
private Set<RuleEntity> inboundRules;
private String createdBy;
private Date createdDate;
private String lastModifiedBy;
private Date lastModifiedDate;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof QuarantinePolicyEntity)) return false;
QuarantinePolicyEntity that = (QuarantinePolicyEntity) o;
return com.google.common.base.Objects.equal(getQuarantinePolicyId(), that.getQuarantinePolicyId()) &&
com.google.common.base.Objects.equal(getCustomerUuid(), that.getCustomerUuid());
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), quarantinePolicyId, customerUuid);
}
}
- I am not able to understand what is
foreignKey
andinverseForeignKey
in@JoinTable
. - Secondly, do we have to mention the FK, RuleEntity table, as how does it know which FK to take?
Thanks.
答案1
得分: 1
JPA文档中是怎么说的?
如果你访问JoinTable
注解文档,你会发现
> foreignKey
(可选)用于在表生成生效时指定或控制与joinColumns
元素对应的列的外键约束生成。
>
> inverseForeignKey
(可选)用于在表生成生效时指定或控制与inverseJoinColumns
元素对应的列的外键约束生成。
你真的需要这些吗?
因此,你可以看到这两个属性在模式生成期间定义了外键约束的创建。而不是外键本身。外键是使用joinColumns
和inverseJoinColumns
属性来定义的。
现在,如果你不设置foreignKey
和inverseForeignKey
,那么默认值是ConstraintMode.PROVIDER_DEFAULT
,这意味着你使用的数据库(这里是Oracle)将决定外键约束的名称。
所以,除非你有需要,否则你实际上不需要显式地提供foreignKey
和inverseForeignKey
。这些都是可选属性。
改善关联的更多方法
- 我不知道这是否是可用的代码。但实际上,这里的
OneToMany
关联没有正确定义。没有joinColumns
和inverseJoinColumns
关联(因此没有告诉哪些列进行映射)。关联应该这样定义
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinTable(name = "join_table_name",
joinColumns = @JoinColumn(name = "column_a"),
inverseJoinColumns = @JoinColumn(name = "column_b"),
foreignKey = @ForeignKey(name = "name_of_the_constraint_for_column_a"),
inverseForeignKey = @ForeignKey(name = "name_of_the_constraint_for_column_b"))
private Set<RuleEntity> outboundRules;
- 此外,甚至对于OneToMany关联,你也不需要一个JoinTable。仅一个
JoinColumn
就足够了。思考关联是单向的还是双向的,或者哪一侧是关系的拥有方。你会找到许多选项来优化你的关联。
更多阅读:
英文:
What does the JPA documentation say?
If you visit the JoinTable
annotation doc you will find
> foreignKey
(Optional) Used to specify or control the generation of a foreign key constraint for the columns corresponding to the
> joinColumns
element when table generation is in effect.
>
> inverseForeignKey
(Optional) Used to specify or control the generation of a foreign key constraint for the columns corresponding
> to the inverseJoinColumns
element when table generation is in effect.
Do you really need these?
So you can see these two attributes are defining the foreign key contraint creation during schema generation. Not the foreign key itself. The foreign keys are defined with the joinColumns
and inverseJoinColumns
attribute.
Now if you dont put those foreignKey
and inverseForeignKey
, then the default value is ConstraintMode.PROVIDER_DEFAULT
that means the database you are using (Oracle here) will decide the name of the foreign key constraint.
So you dont really need to explicitly provide the foreignKey
and inverseForeignKey
unless you want. These are optional attribute.
More ways to improve the association
-
I dont know wheather its a working code or not. But actually the
OneToMany
association is not properly defined here. There is nojoinColumns
andinverseJoinColumns
association (so nothing is telling which column to map). The association should be defined this way@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) @JoinTable(name = "join_table_name", joinColumns = @JoinColumn(name = "column_a"), inverseJoinColumns = @JoinColumn(name = "column_b"), foreignKey = @ForeignKey(name = "name_of_the_constraint_for_column_a"), inverseForeignKey = @ForeignKey(name = "name_of_the_constraint_for_column_b")) private Set<RuleEntity> outboundRules;
-
Moreover you dont even need a JoinTable for a OneToMany association either. Simply a
JoinColumn
should do the job. Think about the association, if its unidirectional or bi directional or which side is the owning side of the relationship. You will find handful of options to optimize your association.
More read:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论