How do I disable Hibernate foreign key constraint on a bidirectional association?
Asked Answered
C

2

17

I am trying to disable the foreign key constraint being generated on my bidirectional association. I have managed to do this for all my unidirectional associations, but for some reason it is not working here.

I do know about the bug with ContraintMode.NO_CONSTRAINT that was recently fixed in Hibernate 5.x, and I am running the latest Hibernate 5.2.6.

My annotations presently look like this:

class Parent {
  @OneToMany(mappedBy="parent", cascade=CascadeType.ALL, orphanRemoval=true)
  @OrderColumn(name="childIndex")
  public List<Child> getChildren() {
    return children;
  }
}

class Child {
  @ManyToOne(optional=false)
  @JoinColumn(name="parent", foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
  public Parent getParent() {
    return parent;
  }
}

But despite NO_CONSTRAINT, Hibernate is still creating the foreign key constraint on child.parent -> parent.id.

Is there something additional I need to do to suppress the foreign key for the bidirectional case?

Thanks!

Cosmogony answered 18/1, 2017 at 21:24 Comment(0)
S
19

This is known issue in Hibernate, see https://hibernate.atlassian.net/browse/HHH-8805

Solution is to add @org.hibernate.annotations.ForeignKey(name = "none") on the mapped side.

class Parent {

  @OneToMany(mappedBy="parent", cascade=CascadeType.ALL, orphanRemoval=true)
  @OrderColumn(name="childIndex")
  @org.hibernate.annotations.ForeignKey(name = "none")
  public List<Child> getChildren() {
    return children;
  }

}

Note: Prefer the JPA 2.1 introduced javax.persistence.ForeignKey instead. The native annotation is deprecated.

Serous answered 12/9, 2017 at 1:53 Comment(5)
The Note given in this answer is wrong. javax.persistence.ForeignKey is what's used in the OP. It does not work, and it cannot be applied to a field.Tyishatyke
@org.hibernate.annotations.ForeignKey is deprecated now, is there different solution?Welcome
@KonradDrozd If you look at the issue mentioned above, it seems that the issue has been fixed (using @JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))) in Hibernate version 5.3.3 and 5.4.x. I haven't tried it myself, maybe you can give it a try.Serous
@BustanilArifin It works but the IDE shows this warning"The type ForeignKey is deprecated".Abattoir
Isn't there any solution to just disable foreign key auto generation only during testing through configuration?Mundane
D
6

Addition to the @Bustanil Arifin answer:

You can combine @OneToMany and @javax.persistence.ForeignKey in next way:

class Parent {

  @OneToMany(cascade=CascadeType.ALL, orphanRemoval=true)
  @JoinColumn(name = "parent", foreignKey = @javax.persistence.ForeignKey(name = "none"))
  public List<Child> getChildren() {
    return children;
  }

}
Durfee answered 8/1, 2020 at 12:46 Comment(1)
This isn't a suitable solution when using a mappedBy association (where the physical foreign key is stored on the other table); you'll get errors like: "Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn". And Hibernate will try to generate a column where it shouldn't.Lathan

© 2022 - 2024 — McMap. All rights reserved.