Skip to content

Commit

Permalink
allow @JoinColumns(value) to be empty and defaulted
Browse files Browse the repository at this point in the history
this allows foreignKey to be specified independently for multi-column joins

also improve the javadoc for @joincolumn and @JoinColumns

Signed-off-by: Gavin King <gavin@hibernate.org>
  • Loading branch information
gavinking committed Jun 15, 2024
1 parent a3138b1 commit f157b1e
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 20 deletions.
25 changes: 18 additions & 7 deletions api/src/main/java/jakarta/persistence/JoinColumn.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,19 @@
* collection. If the {@code JoinColumn} annotation itself is defaulted,
* a single join column is assumed and the default values apply.
*
* <p>Example:
* <p>Here, a {@linkplain ManyToOne many-to-one association} is mapped
* to a foreign key of the target {@code Address} entity held in the
* table mapped by the {@code Employee} entity:
* {@snippet :
* // In Employee class
* @ManyToOne
* @JoinColumn(name = "ADDR_ID")
* @JoinColumn(name = "ADDR_ID") // join column is in the table for Employee
* public Address getAddress() { return address; }
* }
*
* <p>Example: unidirectional one-to-many association using a foreign key mapping
* <p>In this example, a unidirectional {@linkplain OneToMany one-to-many
* association} is mapped to a foreign key of the {@code Customer} entity
* held in the table mapped by the target {@code Order} entity:
* {@snippet :
* // In Customer class
* @OneToMany
Expand Down Expand Up @@ -177,12 +182,18 @@
String table() default "";

/**
* (Optional) Used to specify or control the generation of a
* foreign key constraint when table generation is in effect.
* If this element is not specified, a default foreign key
* strategy is selected by the persistence provider.
* (Optional) Controls generation of the foreign key constraint
* on this join column when table generation is in effect.
* <p>
* If this element is not specified, and if there is no parent
* {@link JoinColumns @JoinColumns} annotation or if the parent
* {@link JoinColumns @JoinColumns} annotation does not specify
* the {@link JoinColumns#foreignKey foreignKey}, a default
* foreign key strategy is selected by the persistence provider.
*
* @since 2.1
*
* @see JoinColumns#foreignKey
*/
ForeignKey foreignKey() default @ForeignKey(PROVIDER_DEFAULT);

Expand Down
48 changes: 35 additions & 13 deletions api/src/main/java/jakarta/persistence/JoinColumns.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,23 @@
* {@link JoinColumn#name name} and {@link JoinColumn#referencedColumnName
* referencedColumnName}.
*
* <p>Example:
* <p>Since {@code @JoinColumn} is a repeatable annotation, it's not usually
* necessary to specify {@code @JoinColumns} explicitly:
* {@snippet :
* @ManyToOne
* @JoinColumns({
* @JoinColumn(name = "ADDR_ID", referencedColumnName = "ID"),
* @JoinColumn(name = "ADDR_ZIP", referencedColumnName = "ZIP")})
* @JoinColumn(name = "ADDR_ID", referencedColumnName = "ID")
* @JoinColumn(name = "ADDR_ZIP", referencedColumnName = "ZIP")
* public Address getAddress() { return address; }
* }
*
* <p>However, {@code @JoinColumns} is useful for controlling generation of
* multi-column foreign keys:
* {@snippet :
* @ManyToOne
* @JoinColumns(
* value = {@JoinColumn(name = "ADDR_ID", referencedColumnName = "ID"),
* @JoinColumn(name = "ADDR_ZIP", referencedColumnName = "ZIP")},
* foreignKey = @ForeignKey(name = "PERSON_ADDRESS_FK"))
* public Address getAddress() { return address; }
* }
*
Expand All @@ -50,20 +61,31 @@
public @interface JoinColumns {

/**
* The join columns that map the relationship.
* (Optional) The join columns that map the relationship.
* <p>
* If no {@code @JoinColumn}s are specified, the join columns
* are inferred according to the relationship mapping defaults,
* exactly as if the {@code @JoinColumns} annotation was missing.
* This allows the {@link #foreignKey} to be specified when the
* join columns are defaulted.
*/
JoinColumn[] value();
JoinColumn[] value() default {};

/**
* (Optional) Used to specify or control the generation of a
* foreign key constraint when table generation is in effect.
* If both this element and the {@code foreignKey} element of
* any of the {@link JoinColumn} elements are specified, the
* behavior is undefined. If no foreign key annotation element
* is specified in either location, a default foreign key
* strategy is selected by the persistence provider.
* (Optional) Controls generation of the foreign key constraint
* on these join columns when table generation is in effect.
* <ul>
* <li>If both this element and a {@link JoinColumn#foreignKey
* foreignKey} element of one of the {@link JoinColumn}
* annotations are specified, the behavior is undefined.
* <li>If no {@link ForeignKey} annotation is specified in
* either location, a default foreign key strategy is
* selected by the persistence provider.
* </ul>
*
* @since 2.1
*
* @see JoinColumn#foreignKey
*/
ForeignKey foreignKey() default @ForeignKey(PROVIDER_DEFAULT);
}

0 comments on commit f157b1e

Please sign in to comment.