ManyToOne Hibernate 映射中与 MySQL 数据库上的外部复合键相关的未知错误
Unknown Error in ManyToOne Hibernate Mapping related to Foreign Composite Key on MySQL DB
我正在尝试映射 Real_States:
CREATE TABLE REAL_STATES (
address VARCHAR(30) NOT NULL,
admin_id VARCHAR(15) NOT NULL,
real_state_type_id INT(6) NOT NULL,
block VARCHAR(3) NOT NULL,
internal_id INT(5) NOT NULL,
PRIMARY KEY (address, block, internal_id),
FOREIGN KEY (real_state_type_id) REFERENCES REAL_STATE_TYPES (real_state_type_id),
FOREIGN KEY (admin_id) REFERENCES ADMINS (admin_id)
);
与居民有关:
CREATE TABLE RESIDENTS (
resident_id VARCHAR(15) NOT NULL,
resident_name VARCHAR(20) NOT NULL,
resident_last_name VARCHAR(20) NOT NULL,
resident_phone_number VARCHAR(15) NOT NULL,
address VARCHAR(30) NOT NULL,
block VARCHAR(3) NOT NULL,
internal_id INT(5) NOT NULL,
PRIMARY KEY (resident_id),
FOREIGN KEY (address, block, internal_id) REFERENCES REAL_STATES (address, block, internal_id)
);
通过 Real_State 的实体:
@Entity
@Table(name = "real_states")
public class RealState implements Serializable{
private static final long serialVersionUID = 4033627448194380926L;
@EmbeddedId
private RealStateID realStateID;
@Column(name = "real_state_type_id")
@Enumerated(EnumType.ORDINAL)
private RealStateEnum realStateEnum;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "admin_id", insertable = true)
private Admin admin;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumns({@JoinColumn(name="address", referencedColumnName = "address", insertable = false, updatable = false),
@JoinColumn(name="block",referencedColumnName = "block", insertable = false, updatable = false),
@JoinColumn(name="internal_id",referencedColumnName = "internal_id", insertable = false, updatable = false)})
private Resident resident;
使用组合键的嵌入实体:
@Embeddable
public class RealStateID implements Serializable{
private static final long serialVersionUID = 6485406412363395170L;
@Column(name = "address")
private String address;
@Column(name = "block")
private String block;
@Column(name = "internal_id")
private int internal_id;
和居民实体:
@Entity
@Table(name = "residents")
public class Resident implements Serializable {
private static final long serialVersionUID = -9052313410222202916L;
@Id
@Column(name = "resident_id")
private String resident_id;
@Column(name = "resident_name")
private String resident_name;
@Column(name = "resident_last_name")
private String resident_last_name;
@Column(name = "resident_phone_number")
private String resident_phone_number;
@Column(name = "address")
private String address;
@Column(name = "block")
private String block;
@Column(name = "internal_id")
private int internal_id;
@OneToMany(mappedBy = "resident", fetch= FetchType.EAGER)
private List<RealState> realStates;
对于这种特殊情况,我收到下一个错误:
22:18:32,825 WARN [org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl] (ServerService Thread Pool -- 79) GenerationTarget encountered exception accepting command : Error executing DDL "alter table real_states add constraint FKeggvad6claf4gvemna1xdk2tm foreign key (address, block, internal_id) references residents (address, block, internal_id)" via JDBC Statement: org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table real_states add constraint FKeggvad6claf4gvemna1xdk2tm foreign key (address, block, internal_id) references residents (address, block, internal_id)" via JDBC Statement
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67)
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlString(AbstractSchemaMigrator.java:559)
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlStrings(AbstractSchemaMigrator.java:504)
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applyForeignKeys(AbstractSchemaMigrator.java:433)
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:249)
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:114)
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:183)
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:72)
at org.hibernate@5.3.20.Final//org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:310)
at org.hibernate@5.3.20.Final//org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:467)
at org.hibernate@5.3.20.Final//org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1250)
at org.hibernate.jipijapa-hibernate5-3@23.0.1.Final//org.jboss.as.jpa.hibernate5.TwoPhaseBootstrapImpl.build(TwoPhaseBootstrapImpl.java:44)
at org.jboss.as.jpa@23.0.1.Final//org.jboss.as.jpa.service.PersistenceUnitServiceImpl.run(PersistenceUnitServiceImpl.java:170)
at org.jboss.as.jpa@23.0.1.Final//org.jboss.as.jpa.service.PersistenceUnitServiceImpl.run(PersistenceUnitServiceImpl.java:128)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at org.wildfly.security.elytron-private@1.15.3.Final//org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:664)
at org.jboss.as.jpa@23.0.1.Final//org.jboss.as.jpa.service.PersistenceUnitServiceImpl.run(PersistenceUnitServiceImpl.java:213)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
at java.base/java.lang.Thread.run(Thread.java:834)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.JBossThread.run(JBossThread.java:513)
Caused by: java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`real_state`.`#sql-3e28_118`, CONSTRAINT `FKeggvad6claf4gvemna1xdk2tm` FOREIGN KEY (`address`, `block`, `internal_id`) REFERENCES `residents` (`address`, `block`, `internal_id`))
at com.mysql@8.0.22//com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117)
at com.mysql@8.0.22//com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql@8.0.22//com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql@8.0.22//com.mysql.cj.jdbc.StatementImpl.executeInternal(StatementImpl.java:764)
at com.mysql@8.0.22//com.mysql.cj.jdbc.StatementImpl.execute(StatementImpl.java:648)
at org.jboss.ironjacamar.jdbcadapters@1.4.27.Final//org.jboss.jca.adapters.jdbc.WrappedStatement.execute(WrappedStatement.java:198)
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:54)
... 22 more
在此之前,我遇到了一个错误,要求我实现“插入应该为假,更新应该为假”,这就是为什么我将这些语句添加到每个 @JoinColumn 注释中的原因,我在 JPA 真的很新,所以我真的很感激任何可以指导我解决这个问题背后原因的建议或帮助。
如果您尝试保存或更新 realstates
,请确保您正确地将 resident
对象设置为 realstate
。错误日志显示保存 realstates
时存在外键冲突,这发生在房地产对象在保存时没有 resident
对象时。
根据您的RESIDENTS
table定义:
CREATE TABLE RESIDENTS (
-- ...
FOREIGN KEY (address, block, internal_id) REFERENCES REAL_STATES (address, block, internal_id)
);
Resident - RealState
关联的所有者端应在 Resident
实体中定义,如下所示:
@Entity
@Table(name = "residents")
public class Resident implements Serializable {
// ...
@ManyToOne
@JoinColumns({
@JoinColumn(name="address", referencedColumnName = "address"),
@JoinColumn(name="block", referencedColumnName = "block"),
@JoinColumn(name="internal_id", referencedColumnName = "internal_id")
})
private RealState realState;
}
然后是 RealState
实体中的 mappedBy
侧。
@Entity
@Table(name = "real_states")
public class RealState implements Serializable {
// ...
@OneToMany(mappedBy = "realState", fetch= FetchType.EAGER, cascade = CascadeType.ALL)
private List<Resident> resident;
}
我正在尝试映射 Real_States:
CREATE TABLE REAL_STATES (
address VARCHAR(30) NOT NULL,
admin_id VARCHAR(15) NOT NULL,
real_state_type_id INT(6) NOT NULL,
block VARCHAR(3) NOT NULL,
internal_id INT(5) NOT NULL,
PRIMARY KEY (address, block, internal_id),
FOREIGN KEY (real_state_type_id) REFERENCES REAL_STATE_TYPES (real_state_type_id),
FOREIGN KEY (admin_id) REFERENCES ADMINS (admin_id)
);
与居民有关:
CREATE TABLE RESIDENTS (
resident_id VARCHAR(15) NOT NULL,
resident_name VARCHAR(20) NOT NULL,
resident_last_name VARCHAR(20) NOT NULL,
resident_phone_number VARCHAR(15) NOT NULL,
address VARCHAR(30) NOT NULL,
block VARCHAR(3) NOT NULL,
internal_id INT(5) NOT NULL,
PRIMARY KEY (resident_id),
FOREIGN KEY (address, block, internal_id) REFERENCES REAL_STATES (address, block, internal_id)
);
通过 Real_State 的实体:
@Entity
@Table(name = "real_states")
public class RealState implements Serializable{
private static final long serialVersionUID = 4033627448194380926L;
@EmbeddedId
private RealStateID realStateID;
@Column(name = "real_state_type_id")
@Enumerated(EnumType.ORDINAL)
private RealStateEnum realStateEnum;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "admin_id", insertable = true)
private Admin admin;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumns({@JoinColumn(name="address", referencedColumnName = "address", insertable = false, updatable = false),
@JoinColumn(name="block",referencedColumnName = "block", insertable = false, updatable = false),
@JoinColumn(name="internal_id",referencedColumnName = "internal_id", insertable = false, updatable = false)})
private Resident resident;
使用组合键的嵌入实体:
@Embeddable
public class RealStateID implements Serializable{
private static final long serialVersionUID = 6485406412363395170L;
@Column(name = "address")
private String address;
@Column(name = "block")
private String block;
@Column(name = "internal_id")
private int internal_id;
和居民实体:
@Entity
@Table(name = "residents")
public class Resident implements Serializable {
private static final long serialVersionUID = -9052313410222202916L;
@Id
@Column(name = "resident_id")
private String resident_id;
@Column(name = "resident_name")
private String resident_name;
@Column(name = "resident_last_name")
private String resident_last_name;
@Column(name = "resident_phone_number")
private String resident_phone_number;
@Column(name = "address")
private String address;
@Column(name = "block")
private String block;
@Column(name = "internal_id")
private int internal_id;
@OneToMany(mappedBy = "resident", fetch= FetchType.EAGER)
private List<RealState> realStates;
对于这种特殊情况,我收到下一个错误:
22:18:32,825 WARN [org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl] (ServerService Thread Pool -- 79) GenerationTarget encountered exception accepting command : Error executing DDL "alter table real_states add constraint FKeggvad6claf4gvemna1xdk2tm foreign key (address, block, internal_id) references residents (address, block, internal_id)" via JDBC Statement: org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table real_states add constraint FKeggvad6claf4gvemna1xdk2tm foreign key (address, block, internal_id) references residents (address, block, internal_id)" via JDBC Statement
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67)
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlString(AbstractSchemaMigrator.java:559)
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlStrings(AbstractSchemaMigrator.java:504)
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applyForeignKeys(AbstractSchemaMigrator.java:433)
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:249)
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:114)
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:183)
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:72)
at org.hibernate@5.3.20.Final//org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:310)
at org.hibernate@5.3.20.Final//org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:467)
at org.hibernate@5.3.20.Final//org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1250)
at org.hibernate.jipijapa-hibernate5-3@23.0.1.Final//org.jboss.as.jpa.hibernate5.TwoPhaseBootstrapImpl.build(TwoPhaseBootstrapImpl.java:44)
at org.jboss.as.jpa@23.0.1.Final//org.jboss.as.jpa.service.PersistenceUnitServiceImpl.run(PersistenceUnitServiceImpl.java:170)
at org.jboss.as.jpa@23.0.1.Final//org.jboss.as.jpa.service.PersistenceUnitServiceImpl.run(PersistenceUnitServiceImpl.java:128)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at org.wildfly.security.elytron-private@1.15.3.Final//org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:664)
at org.jboss.as.jpa@23.0.1.Final//org.jboss.as.jpa.service.PersistenceUnitServiceImpl.run(PersistenceUnitServiceImpl.java:213)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
at java.base/java.lang.Thread.run(Thread.java:834)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.JBossThread.run(JBossThread.java:513)
Caused by: java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`real_state`.`#sql-3e28_118`, CONSTRAINT `FKeggvad6claf4gvemna1xdk2tm` FOREIGN KEY (`address`, `block`, `internal_id`) REFERENCES `residents` (`address`, `block`, `internal_id`))
at com.mysql@8.0.22//com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117)
at com.mysql@8.0.22//com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql@8.0.22//com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql@8.0.22//com.mysql.cj.jdbc.StatementImpl.executeInternal(StatementImpl.java:764)
at com.mysql@8.0.22//com.mysql.cj.jdbc.StatementImpl.execute(StatementImpl.java:648)
at org.jboss.ironjacamar.jdbcadapters@1.4.27.Final//org.jboss.jca.adapters.jdbc.WrappedStatement.execute(WrappedStatement.java:198)
at org.hibernate@5.3.20.Final//org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:54)
... 22 more
在此之前,我遇到了一个错误,要求我实现“插入应该为假,更新应该为假”,这就是为什么我将这些语句添加到每个 @JoinColumn 注释中的原因,我在 JPA 真的很新,所以我真的很感激任何可以指导我解决这个问题背后原因的建议或帮助。
如果您尝试保存或更新 realstates
,请确保您正确地将 resident
对象设置为 realstate
。错误日志显示保存 realstates
时存在外键冲突,这发生在房地产对象在保存时没有 resident
对象时。
根据您的RESIDENTS
table定义:
CREATE TABLE RESIDENTS (
-- ...
FOREIGN KEY (address, block, internal_id) REFERENCES REAL_STATES (address, block, internal_id)
);
Resident - RealState
关联的所有者端应在 Resident
实体中定义,如下所示:
@Entity
@Table(name = "residents")
public class Resident implements Serializable {
// ...
@ManyToOne
@JoinColumns({
@JoinColumn(name="address", referencedColumnName = "address"),
@JoinColumn(name="block", referencedColumnName = "block"),
@JoinColumn(name="internal_id", referencedColumnName = "internal_id")
})
private RealState realState;
}
然后是 RealState
实体中的 mappedBy
侧。
@Entity
@Table(name = "real_states")
public class RealState implements Serializable {
// ...
@OneToMany(mappedBy = "realState", fetch= FetchType.EAGER, cascade = CascadeType.ALL)
private List<Resident> resident;
}