Play Framework 2.7.3数据库演化不一致及SQL生成错误求助
我来帮你一步步排查和解决这个问题——你现在遇到的是Evolutions自动生成错误SQL、手动修改后被覆盖,同时数据库状态不一致的报错,咱们逐个击破:
1. 阻止Evolution脚本被自动覆盖
首先要解决的是手动修改SQL后被复原的问题,这通常是因为Play或Ebean在自动重新生成演化脚本。你需要做以下配置调整:
修改application.conf
添加/修改这些配置,关闭自动DDL执行和自动演化应用:
# 关闭Ebean自动执行DDL(避免和Evolutions冲突) ebean.default.runDdl = false # 关闭Play Evolutions的自动应用,改为手动控制 play.evolutions.autoApply = false play.evolutions.autoApplyDowns = false
检查build.sbt
确保没有开启自动生成演化脚本的设置,如果有类似playEbeanGenerateEvolutions := true的配置,要删除或设为false。另外你当前的build.sbt里重复添加了jdbc依赖,建议去掉重复项,整理后如下:
name := """MyFirstPlay""" organization := "com.example" version := "1.0-SNAPSHOT" lazy val root = (project in file(".")).enablePlugins(PlayJava, PlayEbean) scalaVersion := "2.13.0" libraryDependencies ++= Seq( evolutions, jdbc, guice, javaJdbc, javaWs, "mysql" % "mysql-connector-java" % "8.0.16", "javax.xml.bind" % "jaxb-api" % "2.3.1", "javax.activation" % "activation" % "1.1.1", "org.glassfish.jaxb" % "jaxb-runtime" % "2.3.2" ) playEbeanModels in Compile := Seq("models.*") playEbeanDebugLevel := 4
2. 修复数据库不一致状态
现在数据库处于InconsistentDatabase状态,需要先手动清理演化记录:
- 登录你的MySQL数据库:
mysql -u root -p
- 切换到目标数据库:
use playstudent;
- 查看
play_evolutions表的演化记录:
SELECT * FROM play_evolutions;
- 找到状态为
failed或applied_incomplete的记录,删除它(假设是ID为1的演化脚本):
DELETE FROM play_evolutions WHERE id = 1;
完成后重启Play应用,访问http://localhost:9000/@evolutions,按照页面提示手动应用你修改后的正确演化脚本。
3. 生成正确的SQL脚本
自动生成的SQL错误通常和模型注解、数据库兼容性有关,你可以从这几点排查:
检查模型类注解
比如String字段默认长度可能超过MySQL的varchar限制,显式指定长度:
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; @Entity public class Student { @Id private Long id; @Column(length = 255) // 显式指定长度,避免MySQL报错 private String name; // 其他字段和 getter/setter }
如果使用日期时间字段,建议用java.time.LocalDateTime替代java.util.Date,适配MySQL 8.0的驱动:
import java.time.LocalDateTime; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; @Entity public class Student { // ... @Column private LocalDateTime createTime; // ... }
优化MySQL连接URL
你当前的时区设置EST5EDT可能存在兼容性问题,建议换成UTC或本地时区,比如:
db.default.url="jdbc:mysql://localhost:3306/playstudent?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8mb4"
添加useUnicode=true&characterEncoding=utf8mb4也能避免字符编码相关的SQL错误。
4. 验证最终流程
- 确保
conf/evolutions/default/1.sql(对应你的演化版本)是手动编写的正确SQL脚本; - 重启Play应用,访问
/@evolutions页面确认脚本正确,然后点击应用; - 检查数据库表是否正确创建,应用是否正常运行。
内容的提问来源于stack exchange,提问作者ndahigeze yesse jean lini

