添加表关系时找不到表

时间:2018-07-28 11:43:17

标签: java jpa spring-data-jpa jpa-2.0

我想在Spring中使用JPA。我试图实现这一点:

主表商家:

@Entity
@Table
public class Merchants {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "merchantId", updatable = false, nullable = false)
  private int merchantId;

  @Column
  private String name;

  @OneToMany(mappedBy="merchants")
  private List<Terminals> terminals;

  @Column
  private String login;
}

包含商家ID的第二张表:

@Entity
@Table
public class Terminals {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "id", updatable = false, nullable = false)
  private int id;

  @ManyToOne(fetch=FetchType.LAZY)
  @JoinColumn(name="merchantId")
  private Merchants merchants;

  @Column
  private String mode;
}

但是当我部署代码时,我得到了异常:

Caused by: java.sql.SQLException: Table 'production.terminals' doesn't exist
Query is: alter table terminals drop foreign key FKbemlf2t70j5blgdda69vyl032

当我删除表关系代码时,表的创建没有错误。 有什么解决办法吗?

编辑:

MariaDB [production]> show tables;
+------------------------------+
| Tables_in_production |
+------------------------------+
| hibernate_sequence           |
| merchants                    |
| terminals                    |
+------------------------------+
3 rows in set (0.00 sec)

MariaDB [production]> 

application.properties

spring.jmx.enabled=false
spring.datasource.jndi-name=java:/global/production
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = create-drop
request.limit=300000

2 个答案:

答案 0 :(得分:1)

您在这里看到的问题与您在application.properties文件中定义的DDL策略有关。

似乎您使用create-drop来告诉Hibernate在会话结束后使用它创建然后销毁数据库模式。 Hibernate通常支持以下DDL指令:

  1. 更新(必要时更新架构)
  2. 创建(创建架构并销毁先前的数据)
  3. create-drop(在会话结束时创建然后销毁模式)
  4. 无(禁用ddl处理)
  5. 验证(验证架构,不对数据库进行任何更改)

无论如何,我已经看到使用create-drop DDL策略和H2数据库进行集成测试时会发生这种情况。我从没有花更多的时间对此进行研究,但是它可能归因于您使用的方言,对于标准MySQL而言,这种情况不会发生。

尽管如此,我还是倾向于避免使用Hibernate的DDL函数来创建或更改数据库模式-尤其是在生产部署中。尽管它在大多数情况下都能正常工作,但使用自动DDL功能可能会导致许多讨厌的副作用。

因此,我倾向于将Hibernate的DDL函数设置为validate,并使用Flyway https://flywaydb.org/处理从创建到数据更改的所有所需的模式更改。

这样,我可以运行自己的sql脚本来执行所需的任何更改。我认为使用flyway是一种更好的选择,因为它允许以下操作:

  • 验证模式更改。

  • 一种更安全的方式来处理任何数据库更改。

  • 允许使用VCS控制架构更改(实际脚本)。

通常它集成得很好,并且设置非常容易,所以我建议您看看它。

答案 1 :(得分:0)

在sqlyog或mysql工作台或任何编辑器中运行此“更改表终端删除外键FKbemlf2t70j5blgdda69vyl032”查询,然后启动应用程序,否则删除表并启动应用程序,因为已经映射了错误的外键。所以我们必须手动输入错误的foregin键