我尝试以n:m关系连接披萨和配料,而所有披萨都将配料作为配料的属性列表。但是在Relationstable中,当我创建一个新的Pizza并尝试提交时,Relationtable中的PizzaID出现错误。
关系表:
CREATE TABLE `Pizza_Ingredience_Relation` (
`PizzaID` int(11) NOT NULL,
`IngredientID` int(11) NOT NULL,
`Amount` int(11) NOT NULL,
`Volume_Unit` varchar(1) NOT NULL,
PRIMARY KEY (`PizzaID`,`IngredientID`),
KEY `FKc58en2gx5a8n1swmu9tda345` (`IngredientID`),
CONSTRAINT `FK_IngredienceId` FOREIGN KEY (`IngredientID`) REFERENCES `Zutatenliste` (`ID`),
CONSTRAINT `FKc58en2gx5a8n1swmu9tda345` FOREIGN KEY (`IngredientID`) REFERENCES `Zutatenliste` (`ID`),
CONSTRAINT `FKhghfxg8raskdydyu8o8msxtfn` FOREIGN KEY (`PizzaID`) REFERENCES `Pizza` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
成分表:
CREATE TABLE `Zutatenliste` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Name` varchar(20) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
披萨桌:
CREATE TABLE `Pizza` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Name` varchar(20) NOT NULL,
`PreisKlein` double NOT NULL,
`PreisMittel` double NOT NULL,
`PreisGroß` double NOT NULL,
`PreisFamilie` double NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `ID` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
我有两个冬眠实体,一个是披萨实体,另一个是成分实体:
package Model.PizzenDB.SQLConnectionClasses.MySQL;
import Model.PizzenDB.Pizza;
import org.hibernate.annotations.CollectionId;
import org.hibernate.annotations.Where;
import javax.persistence.*;
import java.util.LinkedList;
import java.util.Set;
@Entity
@Table(name = "Pizza")
public class MySQLPizzaHibernateEntity {
@Id
@Column(name = "ID")
private int id;
@Column(name = "Name")
private String name;
@Column(name = "PreisKlein")
private double smallPrice;
@Column(name = "PreisMittel")
private double middlePrice;
@Column(name = "PreisGroß")
private double bigPrice;
@Column(name = "PreisFamilie")
private double familyPrice;
@ManyToMany(cascade = { CascadeType.ALL })
@JoinTable(
name = "Pizza_Ingredience_Relation",
joinColumns = { @JoinColumn(name = "PizzaID", referencedColumnName = "ID") },
inverseJoinColumns = { @JoinColumn(name = "IngredientID") }
)
private Set<MySQLIngredientWithAmountHibernateEntity> ingredience;
public MySQLPizzaHibernateEntity(String name, double smallPrice, double middlePrice, double bigPrice, double familyPrice) {
this.name = name;
this.smallPrice = smallPrice;
this.middlePrice = middlePrice;
this.bigPrice = bigPrice;
this.familyPrice = familyPrice;
}
public MySQLPizzaHibernateEntity() {
}
}
@Entity
@Table(name = "Zutatenliste")
@SecondaryTable(name = "Pizza_Ingredience_Relation", pkJoinColumns = @PrimaryKeyJoinColumn(name = "IngredientID", referencedColumnName = "ID"))
public class MySQLIngredientWithAmountHibernateEntity {
@Id
@Column(name = "ID")
private int id;
@Column(name = "Name")
private String name;
@Column(table = "Pizza_Ingredience_Relation", name="Amount")
private int amount;
@Column(table = "Pizza_Ingredience_Relation", name = "Volume_Unit")
private char unit;
public MySQLIngredientWithAmountHibernateEntity(String name) {
this.name = name;
}
public MySQLIngredientWithAmountHibernateEntity() {
this("");
}
}
我收到以下错误消息:
20:41:45 [main] [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] ERROR - Field 'PizzaID' doesn't have a default value
20:41:45 [main] [org.hibernate.internal.ExceptionMapperStandardImpl] ERROR - HHH000346: Error during managed flush [org.hibernate.exception.GenericJDBCException: could not execute statement]
我不确定具体问题出在哪里,我想这与PizzaID外键有关,并且设置不正确。
答案 0 :(得分:1)
对于多对多关系,您正在使用带有额外列的中间表,并且需要Embeddable键来构成由Pizza和Ingredient对象(名称缩写)组成的键。像这样:
@Embeddable
public class PizzaIngredientPk {
private MySQLPizzaHibernateEntity pizza;
private MySQLIngredientWithAmountHibernateEntity ingredient;
@ManyToOne
public MySQLPizzaHibernateEntity getPizza() {
return pizza;
}
public void setPizza(MySQLPizzaHibernateEntity pizza) {
this.pizza = pizza;
}
@ManyToOne
public MySQLIngredientWithAmountHibernateEntity getIngredient() {
return ingredient;
}
public void setIngredientID(MySQLIngredientWithAmountHibernateEntity ingredient) {
this.ingredient = ingredient;
}
}
然后它将作为MySQLIngredientWithAmountHibernateEntity中的嵌入式密钥
@EmbeddedId
PizzaIngredientPk pk = new PizzaIngredientPk();
但是这不适用于用于一对一关系的Secondarytable。 @SecondaryTable要求映射必须使用主键,但是在这种情况下,嵌入式ID将成为PK。实际上,您的设计存在缺陷。您正在尝试使多对多关系中的一侧一对一。
根据JPA文档,使用EmbeddedId注释时,必须只有一个EmbeddedId注释,而没有Id注释。
答案 1 :(得分:0)
尝试指定为休眠时自动产生主键。将此注释放在ID字段上方,然后重新创建数据库。
@GeneratedValue(strategy = GenerationType.IDENTITY)
请参阅:https://thoughts-on-java.org/hibernate-tips-use-auto-incremented-column-primary-key/