java - 如何设置 Spring/HIbernate JPA @Entiry 创建自动递增列(无 id)

标签 java spring hibernate jpa spring-data-jpa

问题

  1. 我想知道是否有办法设置一个 @Entity 来创建一个 int column,每次创建一个不是 @Id 的新对象时,该列可以自动递增?
  2. 如果可能的话,我怎样才能给它一个初始值

我已经看到了一种创建单独的@Entity并使用@OneToOne映射的方法,但我想知道是否有任何方法可以直接在一个@Entity中执行此操作

我已经阅读了各种类似的文章,但仍然无法找到解决方案。

这个特定的类没有自动生成它的@Id

@Entity

private @Id String serial;

@SequenceGenerator(name = "port_gen", sequenceName = "port_gen",  initialValue = 4700)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "port_gen")
private @JsonIgnore int port;

我尝试了不同的GenerationType

堆栈跟踪:

org.springframework.orm.jpa.JpaSystemException: could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement
        at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:314)
        at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:225)
        at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:131)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
        at com.sun.proxy.$Proxy123.save(Unknown Source)
        at com.miw.mcb.adbservice.service.DeviceService.registerDevice(DeviceService.java:121)
        at com.miw.mcb.adbservice.service.DeviceService.registerAllDevices(DeviceService.java:168)
        at com.miw.mcb.adbservice.InitialRunner.registerDevices(InitialRunner.java:75)
        at com.miw.mcb.adbservice.InitialRunner.run(InitialRunner.java:37)
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:806)
        at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:790)
        at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:777)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180)
        at com.miw.mcb.adbservice.AdbService.main(AdbService.java:21)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:478)
        at java.lang.Thread.run(Thread.java:745)
Caused by: org.hibernate.exception.GenericJDBCException: could not execute statement
        at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:211)
        at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:62)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3124)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3581)
        at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:104)
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:465)
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:351)
        at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
        at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
        at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1258)
        at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)
        at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
        at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
        at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:77)
        at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
        ... 31 more
Caused by: java.sql.SQLException: Field 'port' doesn't have a default value
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
        at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
        at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073)
        at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009)
        at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5094)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994)
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208)
        ... 45 more

最佳答案

两种可能的选择:

  1. 在数据库中定义一个触发器,用于调用序列并设置列的值。
  2. 声明自定义 @SQLInsert通过在插入语句中包含序列调用,在实体级别上(示例 herehere )。

在这两种情况下,您都需要 refresh如果您想在持久化实例后立即使用生成的值,则保存后的实体实例。

关于java - 如何设置 Spring/HIbernate JPA @Entiry 创建自动递增列(无 id),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38535126/

相关文章:

java - 图数据库 (neo4j) 与关系数据库。在设计方面需要帮助

java - 是否可以在不启动相应应用程序的情况下在android中发送电子邮件?

java - 带有 Spring Boot 建议的 AOP 未触发

java - 返回 Hibernate SessionFactory 对象的 buildSessionFactory() 方法已被弃用,如何解决?

java - EntityManager 持久化和合并在 @Transactional 方法中不起作用

java - hibernate :OutOfMemoryError: PermGen space

java - 如何在每次触摸屏幕时绘制一个新的圆圈?

java - Spring - 引用 Java bean 在 XML 中创建 bean,反之亦然

spring - 创建自动配置 spring 库到 spring-boot 应用程序

java - URI 的编码路径在内置于 JAR 或未内置时表现不同