在我的设置中,datasource.initialization
设置为始终。
问题
spring.jpa.hibernate.ddl-auto = create
每次启动应用程序或对应用程序进行更改时,它都按照设计工作,重新创建数据库,然后从data.sql
但是当我从create
更改为update
时,我得到了MySQLIntegrityConstraintViolationException。更新意味着它只在Hibernate检测到更改权限时才开始工作?那我为什么要重复录入?
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '10001' for key 'PRIMARY'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_144]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_144]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_144]
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_144]
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) ~[mysql-connector-java-5.1.46.jar:5.1.46]
at com.mysql.jdbc.Util.getInstance(Util.java:408) ~[mysql-connector-java-5.1.46.jar:5.1.46]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:936) ~[mysql-connector-java-5.1.46.jar:5.1.46]
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3976) ~[mysql-connector-java-5.1.46.jar:5.1.46]
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3912) ~[mysql-connector-java-5.1.46.jar:5.1.46]
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2530) ~[mysql-connector-java-5.1.46.jar:5.1.46]
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2683) ~[mysql-connector-java-5.1.46.jar:5.1.46]
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2482) ~[mysql-connector-java-5.1.46.jar:5.1.46]
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2440) ~[mysql-connector-java-5.1.46.jar:5.1.46]
at com.mysql.jdbc.StatementImpl.executeInternal(StatementImpl.java:845) ~[mysql-connector-java-5.1.46.jar:5.1.46]
at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:745) ~[mysql-connector-java-5.1.46.jar:5.1.46]
at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95) ~[HikariCP-2.7.8.jar:na]
at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java) ~[HikariCP-2.7.8.jar:na]
at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:473) ~[spring-jdbc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
... 73 common frames omitted
Application.properties
## DB confige
....
## Hibernate Properties
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.datasource.initialization-mode=always
spring.jpa.hibernate.ddl-auto = create ###### <---- Problem
data.sql
insert into course (id, name, created_date, last_updated_date)
values(10001, 'JPA in 50 steps', NOW(), NOW()),
(10002, 'Spring', NOW(), NOW()),
(10003, 'Spring Boot', NOW(), NOW());
insert into review(id, description, rating, course_id)
values(50001, 'Okey course', '3', 10001),
(50002, 'Awesome course', '5', 10001),
(50003, 'Greate Course', '4', 10003);
insert into passport(id, number)
values(40001, 'ASD2342324'),
(40002, 'NMWO23423'),
(40003, 'POOI9098473');
insert into student(id, name, passport_id)
values(20001, 'Ranga', 40001),
(20002, 'Adam', 40002),
(20003, 'Jane', 40003);
insert into student_course(student_id, course_id)
values(20001,10001),
(20002,10001),
(20003,10001),
(20001,10003);
答案 0 :(得分:1)
问题是
每次启动应用程序时,spring.jpa.hibernate.ddl-auto = create
都会删除数据库并重新创建。
虽然spring.jpa.hibernate.ddl-auto = update
将触发查询以根据实体更改更新您的数据库,而不会丢弃它或任何数据。
因此,对于更新以及始终运行的data.sql
,它显然会插入已存在的行。
作为快速修复,您可以设置spring.datasource.continue-on-error
属性并忽略data.sql
失败。
但是,根据文档中的建议,使用Flyway
或Liquibase
可能值得学习,因为它们比ddl-auto = update
更强大。
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html