【问题标题】:Hibernate ManyToMany Bidirectional mapping throw DDL ExceptionHibernate ManyToMany 双向映射抛出 DDL 异常
【发布时间】:2019-07-19 09:11:01
【问题描述】:

我有 4 个实体。 UserRoleEmployeeRoleAccessPermission。 4 个实体通过外键相互连接。我在与 User 和 EmployeeRole 的双向多对多关系时遇到了问题。关系映射的用户表所有者。我还需要从 EmployeeRole 表中访问用户信息。所以我在两个实体中建立了双向 OneToMany 关系。

我在运行代码时遇到 DDL 异常。 请帮我解决这个问题。我在谷歌中尝试了很多搜索。

用户实体:

@Entity
@Table(name="user")
public class User{

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idgenerator")
@SequenceGenerator(initialValue = 1, name = "idgenerator", sequenceName = "usersSeq")
private long id;

@Column(name="company_id")
private String companyId;

@Column(name = "password")
private String password;

@Column(name= "firstname")
private String firstName;

@Column(name = "lastname")
private String lastName;

@Column(name = "email")
private String email;

@Column(name = "active")
private int active;

@ManyToMany(cascade = CascadeType.PERSIST)
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;

@ManyToMany(cascade = CascadeType.PERSIST)
@JoinTable(name = "user_has_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "emp_role_id"))
private Set<EmployeeRole> empRoles = new HashSet<>();
// geters and setters. 
}

EmployeeRole 实体:

@Entity
@Table(name="employeeRole")
public class EmployeeRole extends AbstractData {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idgenerator")
@SequenceGenerator(initialValue = 1, name = "idgenerator", sequenceName = "employeeRoleSeq")
@Column(name = "id", updatable = false, nullable = false)
private long id;

@NotBlank
@Size(min = 1, max = 255)
@Column(name="roleName")
protected String roleName;

@Column(name="roleDescription")
protected String roleDescription;

@ManyToMany(mappedBy="empRoles")  
private Set<User> user = new HashSet<>();
// geters and setters. 
}

错误信息:

alter table user_has_role 
   add constraint FKdtkvc2iy3ph1rkvd67yl2t13m 
   foreign key (user_id) 
   references user (id)

2019-07-19 14:05:38.758  WARN 11756 --- [           main] o.h.t.s.i.ExceptionHandlerLoggedImpl     : GenerationTarget encountered exception accepting command : Error executing DDL "
    alter table user_has_role 
       add constraint FKdtkvc2iy3ph1rkvd67yl2t13m 
       foreign key (user_id) 
       references user (id)" via JDBC Statement

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "
    alter table user_has_role 
       add constraint FKdtkvc2iy3ph1rkvd67yl2t13m 
       foreign key (user_id) 
       references user (id)" via JDBC Statement
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlString(AbstractSchemaMigrator.java:559) [hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlStrings(AbstractSchemaMigrator.java:504) [hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applyForeignKeys(AbstractSchemaMigrator.java:433) [hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:249) [hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:114) [hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:183) [hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:72) [hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:310) [hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:467) [hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:939) [hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) [spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) [spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) [spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) [spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) [spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1821) [spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1758) [spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) [spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) [spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) [spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) [spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) [spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at com.tigerslab.tigererp.TigerErpApplication.main(TigerErpApplication.java:10) ~[classes/:na]
Caused by: java.sql.SQLException: Can't create table `possystem`.`#sql-4a0_17c` (errno: 150 "Foreign key constraint is incorrectly formed")
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) ~[mysql-connector-java-8.0.15.jar:8.0.15]
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) ~[mysql-connector-java-8.0.15.jar:8.0.15]
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java-8.0.15.jar:8.0.15]
    at com.mysql.cj.jdbc.StatementImpl.executeInternal(StatementImpl.java:782) ~[mysql-connector-java-8.0.15.jar:8.0.15]
    at com.mysql.cj.jdbc.StatementImpl.execute(StatementImpl.java:666) ~[mysql-connector-java-8.0.15.jar:8.0.15]
    at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95) ~[HikariCP-3.2.0.jar:na]
    at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java) ~[HikariCP-3.2.0.jar:na]
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:54) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    ... 33 common frames omitted

【问题讨论】:

  • 您的 DDL 架构是否已经存在或者您希望休眠来创建它?
  • 嘿@Habibur-Rahman,我建议您检查表 user_has_role,如果可能,如果它是自动生成的,请删除该表,或者在“user_has_role”中检查存在的 FK。我有一个新的 spring-boot/hibernate 项目,添加了你的类,它创建了所有的表,并成功运行了 user_has_role 的约束命令。
  • 如果不是自动生成的,请检查“user_has_role”或架构中的权限。

标签: java spring hibernate


【解决方案1】:

通常,当您尝试通过键引用表并且它们的长度或数据类型不同时,会发生这种错误。就我所见,我可以给你两个建议。

首先,确保从右侧为EmployeeRole 类指定@JoinTable@JoinColumn(name = "id", referencedColumnName = "user_id") 注释。像这样更新您的映射(请确保将其从 User 实体中删除):

@ManyToMany(mappedBy="empRoles")
@JoinTable(name = "user_has_role", joinColumns = @JoinColumn(name = "emp_role_id"), inverseJoinColumns = @JoinColumn(name = "user_id"))
private Set<User> user = new HashSet<>();

其次,确保为您的 id 使用包装器,因为新创建的实体的 id 为 0(基元不能为 null),而您希望为 null(因为 id 将在插入时生成)。

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idgenerator")
@SequenceGenerator(initialValue = 1, name = "idgenerator", sequenceName = "usersSeq")
private Long id;

【讨论】:

    猜你喜欢
    • 2018-02-24
    • 2016-04-19
    • 2020-04-01
    • 2017-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-31
    相关资源
    最近更新 更多