问题
I have this entity, called FatRabbitCarrot:
@Entity
public class FatRabbitCarrot {
private Long id;
private FatRabbit fatRabbit;
private Carrot carrot;
@Id
@Column(name = "id", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@ManyToOne
@JoinColumn(name = "fatRabbit_id", foreignKey = @ForeignKey(name = "FK_FatRabbitCarrot_fatRabbit"))
public FatRabbit getFatRabbit() {
return fatRabbit;
}
public void setFatRabbit(FatRabbit fatRabbit) {
this.fatRabbit = fatRabbit;
}
@ManyToOne
@JoinColumn(name = "carrot_id", foreignKey = @ForeignKey(name = "FK_FatRabbitCarrot_carrot"))
public Carrot getCarrot() {
return carrot;
}
public void setCarrot(Carrot carrot) {
this.carrot = carrot;
}
}
And it works. Now the above class had field names replaced, but the structure is the same as in our repository.
Then I tried to add a new entity, that has a foreign key to the class above. Let's call this class NutToffee. FatRabbitCarrot have a OneToMany relationship to this new entity, while the entity itself should have a ManyToOne relationship:
@Entity
public class NutToffee {
private Long id;
private String text;
private FatRabbitCarrot fatRabbitCarrot;
@Id
@Column(name = "id", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id){
this.id = id;
}
@Basic
@Column(name = "text")
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
@ManyToOne
@JoinColumn(name="fatRabbitCarrot_id", foreignKey = @ForeignKey(name = "FK_NutToffee_fatRabbitCarrot"))
public FatRabbitCarrot getFatRabbitCarrot() {
return fatRabbitCarrot;
}
public void setFatRabbitCarrot(FatRabbitCarrot fatRabbitCarrot) {
this.fatRabbitCarrot = fatRabbitCarrot;
}
}
Now this seems like a valid class to me. But it doesn't look like it is. We are using Java 8, Hibernate JPA 2.1, Java EE 7 and gradle to build the artifact we want to deploy. We attempt to deploy it on a Wildfly 10 application server, but we get the following error:
[2019-07-08 03:53:45,441] Artifact Gradle : com.solveralynx.wildrunner : fatties.war: java.lang.Exception: {"WFLYCTL0080: Failed services" => {"jboss.persistenceunit.\"fatties.war#FatUnit\"" => "org.jboss.msc.service.StartException in service jboss.persistenceunit.\"fatties.war#FatUnit\": org.hibernate.MappingException: Foreign key (FK_NutToffee_fatRabbitCarrot:NutToffee [fatRabbitCarrot_id])) must have same number of columns as the referenced primary key (FatRabbitCarrot [fatRabbit_id,carrot_id])
Caused by: org.hibernate.MappingException: Foreign key (FK_NutToffee_fatRabbitCarrot:NutToffee [fatRabbitCarrot_id])) must have same number of columns as the referenced primary key (FatRabbitCarrot [fatRabbit_id,carrot_id])"},"WFLYCTL0412: Required services that are not installed:" => ["jboss.persistenceunit.\"fatties.war#FatUnit\""],"WFLYCTL0180: Services with missing/unavailable dependencies" => undefined}
From my understanding, Hibernate found a composite primary key for FatRabbitCarrot? Even though we never defined one? It seems to pick up a fake primary key, where it uses both foreign keys from entity FatRabbitCarrot.
As for my testing. I am confident this is a Hibernate issue. No matter the database state, I always get this error. I tested with various parameters on the getters, that connect that entities, but no success. If I remove both new OneToMany and ManyToOne connections, the artifact deploys.
Does anyone have any idea why Hibernate is doing this?
回答1:
You are using @JoinColumn
annotation incorrectly.
@Entity
public class FatRabbitCarrot {
@Id
@GeneratedValue
private Long id;
@OnToMany
private List<NutToffee> toffies;
}
@Entity
public class NutToffee {
@Id
@GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "fatRabbitCarrot_id")
private FatRabbitCarrot fatRabbitCarrot;
}
This means that you will have association between FatRabbitCarrot
and NutToffee
using a join table. An you will have an additional fatRabbitCarrot_id
column in the NutToffee
table.
You need to use mappedBy
@Entity
public class FatRabbitCarrot {
@Id
@GeneratedValue
private Long id;
@OnToMany(mappedBy = "fatRabbitCarrot")
private List<NutToffee> toffies;
}
@Entity
public class NutToffee {
@Id
@GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "fatRabbitCarrot_id")
private FatRabbitCarrot fatRabbitCarrot;
}
if you don't need the @ManyToOne
association, you can use @JoinColumn
with @OneToMany
without mappedBy
@Entity
public class FatRabbitCarrot {
@Id
@GeneratedValue
private Long id;
@OnToMany
@JoinColumn(name = "fatRabbitCarrot_id")
private List<NutToffee> toffies;
}
@Entity
public class NutToffee {
@Id
@GeneratedValue
private Long id;
}
https://stackoverflow.com/a/37542849/3405171
来源:https://stackoverflow.com/questions/56937114/hibernate-mappingexception-foreign-key-must-have-same-number-of-columns-as-the