java - org.springframework.orm.jpa.JpaSystemException:必须在调用 save() 之前手动分配此类的 id
问题描述
我正在尝试使用SERIAL
type 来生成表的 id。但是在这种情况下,我遇到了一个异常,它说我需要先保存 id。我有另一张这样的桌子,但那张工作正常。
JPA 实体:
@Entity
@Table(name = "pay_appln_data",
uniqueConstraints = {
@UniqueConstraint(columnNames = {"dept_ref_no", "application_no"})
})
public class PayApplnData {
@Id
private Long id;
@Column(name = "dept_ref_no")
private String deptRefNo;
@Column(name = "application_no")
private String applicationNo;
@Column(name = "depositor_name")
private String depositorName;
...
...
}
所用表的 SQL:
CREATE TABLE public.pay_appln_data
(
id serial NOT NULL,
dept_ref_no character varying(16) COLLATE pg_catalog."default" NOT NULL,
application_no character varying(30) COLLATE pg_catalog."default" NOT NULL,
depositor_name character varying(100) COLLATE pg_catalog."default",
...
...
...
CONSTRAINT pay_appln_data_pkey PRIMARY KEY (id),
CONSTRAINT unique_key UNIQUE (dept_ref_no, application_no)
)
DB中的序列presemt是:
CREATE SEQUENCE public.pay_appln_data_id_seq
INCREMENT 1
START 1
MINVALUE 1
MAXVALUE 2147483647
CACHE 1;
ALTER SEQUENCE public.pay_appln_data_id_seq
OWNER TO postgres;
抛出的异常是:
org.springframework.orm.jpa.JpaSystemException: ids for this class must be manually assigned before calling save(): com.rent.mngWithAdmin.model.GRIPSRentPayApplnData; nested exception is org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.rent.mngWithAdmin.model.GRIPSRentPayApplnData
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:353)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
at com.rent.mngWithAdmin.DAO.GRIPSRentPayApplnDataDAOImpl$$EnhancerBySpringCGLIB$$4516a353.saveOrUpdate(<generated>)
at com.rent.mngWithAdmin.service.GRIPSApplicationDataServiceImpl.saveOrUpdate(GRIPSApplicationDataServiceImpl.java:21)
at com.rent.mngWithAdmin.controller.GRIPSRentPayController.rentPayDetails(GRIPSRentPayController.java:301)
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.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.rent.mngWithAdmin.model.GRIPSRentPayApplnData
at org.hibernate.id.Assigned.generate(Assigned.java:33)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:115)
at org.hibernate.event.internal.DefaultMergeEventListener.saveTransientEntity(DefaultMergeEventListener.java:271)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:243)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:175)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:70)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:791)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:778)
at com.rent.mngWithAdmin.DAO.GRIPSRentPayApplnDataDAOImpl.saveOrUpdate(GRIPSRentPayApplnDataDAOImpl.java:22)
at com.rent.mngWithAdmin.DAO.GRIPSRentPayApplnDataDAOImpl$$FastClassBySpringCGLIB$$4bee3df2.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
... 56 more
2021-05-04 12:50:31.403 DEBUG 616 --- [nio-3030-exec-5] org.hibernate.SQL : select tbl.next_val from hibernate_sequences tbl where tbl.sequence_name=? for update of tbl
2021-05-04 12:50:31.406 DEBUG 616 --- [nio-3030-exec-5] org.hibernate.SQL : update hibernate_sequences set next_val=? where next_val=? and sequence_name=?
2021-05-04 12:50:31.455 DEBUG 616 --- [nio-3030-exec-5] org.hibernate.SQL : select tbl.next_val from hibernate_sequences tbl where tbl.sequence_name=? for update of tbl
2021-05-04 12:50:31.456 DEBUG 616 --- [nio-3030-exec-5] org.hibernate.SQL : update hibernate_sequences set next_val=? where next_val=? and sequence_name=?
我不明白为什么它在搜索,hibernate_sequences
而我使用SERIAL
类型作为它的 id?
提前谢谢。
解决方案
您必须使用您为 ID 生成创建的序列。
这可以通过以下注释来完成:
@Id
@SequenceGenerator(name = "pay_appln_data_id_seq", sequenceName = "pay_appln_data_id_seq")
@GeneratedValue(strategy = SEQUENCE, generator = "pay_appln_data_id_seq")
private Long id;
推荐阅读
- java - ArrayList 的后备数组的长度与 ArrayList 的 .size() 不同
- jenkins - Jenkins 和 GitLab——Gitlab Hook 插件是正确的选择吗?
- apache-spark - 从单机到并行处理?
- jquery - 使用jQuery将输入字段中的文本镜像到html跨度?
- java - 用于将文件从 HDFS 复制到 AWS S3 的 Hadoop 服务器连接
- docker - docker-compose volumes version 3 syntax
- elasticsearch - search_after 在指定元素之前返回结果
- sql-server - How to compare the latest two values for a given set of data
- javascript - 调整 $(window) 大小后停止先前执行的函数
- php - php cookie忽略安全标志