如果spring.jpa.hibernate.ddl-auto不是“更新”,则Spring启动运行脚本?

时间:2015-09-18 01:47:30

标签: spring-boot

如果我设置了application.properties,则无论何时加载

都会出错
spring.jpa.hibernate.ddl-auto = update
spring.datasource.data=classpath:/init.dml/TB_FR_LANGUAGE_INFO_INITDATA.sql,classpath:/init.dml/TB_FR_MESSAGE_INFO_INITDATA.sql

只有当spring.jpa.hibernate.ddl-auto是create-drop或create?

时,如何才能弹出启动运行初始脚本?

更新

如何在过去添加一次时避免使用初始数据插入脚本?

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory': Post-processing of FactoryBean's singleton object failed; nested exception is org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of resource class path resource [init.dml/TB_FR_LANGUAGE_INFO_INITDATA.sql]: INSERT INTO TB_FR_LANGUAGE_INFO ( LANGUAGE_SQ, LANGUAGE_ID, LANGUAGE_NM, USE_YN, ORDER_NO, CREATE_DT, CREATE_USR_ID) VALUES ('LAN_000001','KO', 'Korean', 'Y' , 0, NOW(),'superadmin'); nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'LAN_000001' for key 'PRIMARY'
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:116)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1517)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:314)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findDefaultEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:565)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:531)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.resolveEntityManager(PersistenceAnnotationBeanPostProcessor.java:697)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.getResourceToInject(PersistenceAnnotationBeanPostProcessor.java:670)
    at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:169)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:354)
    ... 120 more
Caused by: org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of resource class path resource [init.dml/TB_FR_LANGUAGE_INFO_INITDATA.sql]: INSERT INTO TB_FR_LANGUAGE_INFO ( LANGUAGE_SQ, LANGUAGE_ID, LANGUAGE_NM, USE_YN, ORDER_NO, CREATE_DT, CREATE_USR_ID) VALUES ('LAN_000001','KO', 'Korean', 'Y' , 0, NOW(),'superadmin'); nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'LAN_000001' for key 'PRIMARY'
    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:472)
    at org.springframework.jdbc.datasource.init.ResourceDatabasePopulator.populate(ResourceDatabasePopulator.java:229)
    at org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:48)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.runScripts(DataSourceInitializer.java:153)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.runDataScripts(DataSourceInitializer.java:112)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.onApplicationEvent(DataSourceInitializer.java:105)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.onApplicationEvent(DataSourceInitializer.java:46)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:151)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:128)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:331)
    at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.postProcessAfterInitialization(DataSourceInitializedPublisher.java:69)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1719)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:113)
    ... 130 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'LAN_000001' for key 'PRIMARY'
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:377)
    at com.mysql.jdbc.Util.getInstance(Util.java:360)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:971)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3887)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3823)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2526)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2484)
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:848)
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:742)
    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:457)
    ... 143 more

1 个答案:

答案 0 :(得分:1)

您使用的hibernate ddl-auto正如其名称建议仅适用于DDL,即模式定义。要查看实际代码,请检查此hibernate文件: -

冬眠-ORM /休眠核/ SRC /主/ JAVA /组织/休眠/ cfg中/ SettingsFactory.java

String autoSchemaExport = properties.getProperty( AvailableSettings.HBM2DDL_AUTO );
if ( "validate".equals(autoSchemaExport) ) {
    settings.setAutoValidateSchema( true );
}
else if ( "update".equals(autoSchemaExport) ) {
    settings.setAutoUpdateSchema( true );
}
else if ( "create".equals(autoSchemaExport) ) {
    settings.setAutoCreateSchema( true );
}
else if ( "create-drop".equals( autoSchemaExport ) ) {
    settings.setAutoCreateSchema( true );
    settings.setAutoDropSchema( true );
}
else if ( !StringHelper.isEmpty( autoSchemaExport ) ) {
    LOG.warn( "Unrecognized value for \"hibernate.hbm2ddl.auto\": " + autoSchemaExport );
}

Hibernate不会对这些表中插入/存在的数据进行任何验证,而实际上您希望拥有这些数据。解决问题的方法是以下列形式插入插入,检查数据是否不存在然后只插入: -

INSERT INTO TB_FR_LANGUAGE_INFO ( LANGUAGE_SQ, LANGUAGE_ID, LANGUAGE_NM, USE_YN, ORDER_NO, CREATE_DT, CREATE_USR_ID) 
    VALUES ('LAN_000001','KO', 'Korean', 'Y' , 0, NOW(),'superadmin') 
WHERE NOT EXISTS 
    (select LANGUAGE_SQ from TB_FR_LANGUAGE_INFO where LANGUAGE_SQ = 'LAN_000001');