I have two entities with ManyToMany Relationship. Goal here is to create schema when application start with no foreign key
1). Job.java
package com.govjobportalbackend.entity;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.ForeignKey;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "job")
public class Job extends BasicEntity {
@Column(name = "icon")
private String icon;
@ManyToMany
@JoinTable(
name="job_city",
joinColumns = @JoinColumn(name = "job_id"),
inverseJoinColumns = @JoinColumn(name = "city_id"),
foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT),
inverseForeignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT)
)
private List<City> cities;
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public List<City> getCities() {
return cities;
}
public void setCities(List<City> cities) {
this.cities = cities;
}
}
2). City.java
package com.govjobportalbackend.entity;
import java.util.List;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
@Entity
@DiscriminatorValue(value = "city")
public class City extends JobMetadata {
@ManyToMany(mappedBy = "cities")
private List<Job> jobs;
@Override
public List<Job> getJobs() {
return jobs;
}
@Override
public void setJobs(List<Job> jobs) {
this.jobs = jobs;
}
}
Below property is set in application.properties file
spring.jpa.hibernate.ddl-auto=update
When run the application, it is logging below SQLs in logs and is creating two foreign keys
Hibernate: create table job (id int4 not null, name varchar(255), icon varchar(255), primary key (id))
Hibernate: create table job_city (job_id int4 not null, city_id int4 not null)
Hibernate: create table job_metadata (type varchar(31) not null, id int4 not null, name varchar(255), primary key (id))
Hibernate: alter table if exists job_city add constraint FKiksm0d31mc3osxut4ciaf4uof foreign key (job_id) references job
Hibernate: alter table if exists job_city add constraint FKknw4pf63xt1tvnqrmrjrm5hqq foreign key (city_id) references job_metadata
If I annotate as per below in City.java then it works as expected but as per my "little" research, this bug is fixed in hibernate (so mapped entity is not required to be annotated with depreciated annotation), or may be I am wrong.
@ManyToMany(mappedBy = "cities")
@org.hibernate.annotations.ForeignKey(name = "none")
private List<Job> jobs;
Environment I am using is below;
As SimonMartinelli pointed out, this is most definitely a Hibernate bug. The version that worked for me was:
@JoinTable(
name="job_city",
joinColumns = @JoinColumn(name = "job_id", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT)),
inverseJoinColumns = @JoinColumn(name = "city_id", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT))
)
I found that the functionality breaks when you either (1) use @JoinTable.foreignKey
instead, or (2) omit the name
parameter.