启动Tomcat服务器时roles数据库表被清空的原因咨询
Hey,这个问题我之前帮同事排查过,结合你提到的组件(尤其是RoleRepository,看起来是用了Spring Data JPA),大概率是下面几个原因,咱们一步步拆解:
一、ORM框架的自动DDL配置是头号嫌疑
这是最常见的坑!如果你用了Spring Data JPA,配置文件里的spring.jpa.hibernate.ddl-auto参数如果设成了create或者create-drop,就会出现启动清空表的情况:
create:每次启动应用,Hibernate都会删掉原有表,重新建一张新的,旧数据自然全没了create-drop:更狠,启动建表,应用关闭时还会删表,重启当然也会清空数据
赶紧去检查你的application.properties或application.yml,生产环境这个参数必须设成update(只更新表结构,不会删数据)或者none(完全禁用自动DDL,最稳妥的生产配置)。
二、自定义初始化逻辑搞的鬼
看看你的RoleServiceImpl或者有没有专门的初始化配置类,是不是写了类似这样的代码:
@PostConstruct public void initRoles() { roleRepository.deleteAll(); // 这里直接清空了整个表 // 然后加载那96条预定义数据 }
如果是这样,每次启动都会先删再插,自然会把之前的所有数据(包括后续新增的自定义角色)都清掉。正确的逻辑应该是先判断表是否为空,再决定要不要初始化:
@PostConstruct public void initRoles() { if (roleRepository.count() == 0) { // 只有表空的时候才加载预定义数据 loadPredefinedRoles(); } }
三、数据库本身的存储问题(概率较低)
如果你用的是嵌入式数据库(比如H2、HSQLDB),而且配置的是内存模式(比如H2的jdbc:h2:mem:testdb),那每次重启应用,内存里的数据就会被释放,表自然就空了。这种情况要把数据库配置改成持久化到文件的模式,比如jdbc:h2:file:/path/to/your/database。
回答你的两个疑问
每次启动重新加载预定义数据正常吗?
绝对不正常!除非你的业务需求就是每次启动都重置角色数据(这几乎不可能)。正常逻辑应该是只在第一次启动、表为空的时候加载这些基础数据,不然后续用户新增的角色,一重启就没了,用户肯定炸锅。上线后维护重启会清空数据吗?
如果是DDL配置错了(create/create-drop)或者用了内存数据库,那肯定会清!这在生产环境是致命问题。但如果你把DDL配置改成update/none,并且用的是MySQL、PostgreSQL这种持久化数据库,重启后数据会原封不动保留。
快速排查步骤
- 先查ORM的DDL配置,这是最快定位的点
- 全局搜索代码里的
deleteAll()、truncate这类清空操作,重点看被@PostConstruct、ApplicationRunner、CommandLineRunner标记的方法 - 确认数据库的存储方式,是不是持久化的
内容的提问来源于stack exchange,提问作者Oguzcan

