Spring Boot数据初始化获得异常

时间:2018-04-27 07:48:35

标签: hibernate spring-boot

在我的设置中,datasource.initialization设置为始终。

问题

spring.jpa.hibernate.ddl-auto = create每次启动应用程序或对应用程序进行更改时,它都按照设计工作,重新创建数据库,然后从data.sql

插入数据

但是当我从create更改为update时,我得到了MySQLIntegrityConstraintViolationException。更新意味着它只在Hibernate检测到更改权限时才开始工作?那我为什么要重复录入?

https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#configurations-hbmddl

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);

1 个答案:

答案 0 :(得分:1)

问题是 每次启动应用程序时,spring.jpa.hibernate.ddl-auto = create都会删除数据库并重新创建。

虽然spring.jpa.hibernate.ddl-auto = update将触发查询以根据实体更改更新您的数据库,而不会丢弃它或任何数据。

因此,对于更新以及始终运行的data.sql,它显然会插入已存在的行。

作为快速修复,您可以设置spring.datasource.continue-on-error属性并忽略data.sql失败。

但是,根据文档中的建议,使用FlywayLiquibase可能值得学习,因为它们比ddl-auto = update更强大。

https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html