我正在将Spring Boot 1.4.0.RELEASE
与以下依赖的数据库连接器一起使用
<!-- runtime dependencies -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
还有一个带有
GenerationType.AUTO
策略的实体类,用于生成ID(以下代码不完整)@Entity
@Table(name = "scanner_run")
public class ScannerRun extends BaseObject {
private Long id;
@Id @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
public Long getId() {
return this.id;
}
}
使用H2时,插入新实体没有问题
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
Hibernate生成
insert into scanner_run (id, completed_ts, repository_id, started_ts, success) values (null, ?, ?, ?, ?)
查询并创建新记录。但是与MySQL
spring.datasource.url=jdbc:mysql://localhost/db_dev?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&connectionCollation=utf8_general_ci
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
生成的查询为
insert into scanner_run (completed_ts, repository_id, started_ts, success) values (?, ?, ?, ?)
-ID不在查询中-并且失败。没有其他区别,只需更改
application.properties
即可交换数据库。与较早版本的Hibernate和MySQL连接器相同的代码可与相同的MySQL安装一起使用。 MySQL连接器解析为mysql:mysql-connector-java:jar:5.1.39
你能发现什么不对吗?
日志中的确切消息和异常是:
2016-08-26 14:38:03.964 DEBUG 32555 --- [myScheduler-1] org.hibernate.SQL:插入扫描器运行(completed_ts,repository_id,started_ts,成功)值(?,?,?,?)
2016-08-26 14:38:03.967 WARN 32555 --- [myScheduler-1] o.h.engine.jdbc.spi.SqlExceptionHelper:SQL错误:1364,SQLState:HY000
2016-08-26 14:38:03.967错误32555 --- [myScheduler-1] o.h.engine.jdbc.spi.SqlExceptionHelper:字段'id'没有默认值
2016-08-26 14:38:03.979错误32555 --- [myScheduler-1] o.s.s.s.TaskUtils $ LoggingErrorHandler:计划任务发生意外错误。
jvr.decrex.exception.ExecutionError:无法保存ScannerRun {id = null,repository = / jv-ration / projects / jv-ration / deCrex / jvr-decrex /,startedTs = Fri Aug 26 14:38:03 CEST 2016, completeTs = null}
在jvr.decrex.service.impl.GenericManagerImpl.insert(GenericManagerImpl.java:107)
在jvr.decrex.scanner.service.impl.ScannerRunManagerImpl.createScan(ScannerRunManagerImpl.java:79)
......
在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
在java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617)
在java.lang.Thread.run(Thread.java:745)
由以下原因引起:org.springframework.orm.jpa.JpaSystemException:无法执行语句;嵌套的异常是org.hibernate.exception.GenericJDBCException:无法执行语句
在org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:333)
在org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244)
......
在jvr.decrex.scanner.dao.jpa.ScannerRunDaoJpa $$ EnhancerBySpringCGLIB $$ 5e6c846a.insert()
在jvr.decrex.service.impl.GenericManagerImpl.insert(GenericManagerImpl.java:105)
...省略了21个通用框架
引起原因:org.hibernate.exception.GenericJDBCException:无法执行语句
在org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
在org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)
在org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95)
..........
在com.sun.proxy。$ Proxy126.persist(未知来源)
在jvr.decrex.dao.jpa.GenericDaoJpa.insert(GenericDaoJpa.java:137)
在jvr.decrex.dao.jpa.GenericDaoJpa $$ FastClassBySpringCGLIB $$ 6605cd4e.invoke()
在org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
在org.springframework.aop.framework.CglibAopProxy $ CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)
在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
在org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
...省略了25个通用框架
原因:java.sql.SQLException:字段“ id”没有默认值
在com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078)
......
在com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2376)
在com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2360)
在org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204)
...省略了58个通用框架
我尝试使用旧版本的
5.1.27
mysql-connector-java
,该版本可与旧版本的Hibernate配合使用-抛出相同的错误 最佳答案
您省略了数据库模式,因此要进行大量的猜测。以下是可以说的:AUTO
生成策略意味着JPA提供者可以选择所需的任何内容作为策略。看来,对于MySQL,它使用AUTOINCREMENT
列(相当于IDENTITY
生成策略),对于H2,它可能使用SEQUENCE
(猜测,因为您未提供具体方法)。也许您没有为MySQL的PK列定义AUTOINCREMENT?但是在那种情况下,您不能使用AUTO策略,而是可以。
您可以通过为要部署到的每个数据存储都拥有一个orm.xml来处理它,然后可以根据哪个数据存储区使用不同的生成策略。
或者,选择TABLE
生成策略,并且无论数据存储如何,每次都会插入“ id”列。
或选择IDENTITY
(当您将MySQL AUTOINCREMENT列用作PK,将H2 IDENTITY列用作PK时),因为H2还将使用它(显然,如果您还需要支持没有此类支持)。