JPA Hibernate отсутствует имя столбца в сгенерированном подготовленном операторе

#java #spring #hibernate #jpa

Вопрос:

У меня возникли проблемы с получением аудиторского отчета для размещения на столе.

Ошибка гласит, что поле «changed_by» не имеет значения по умолчанию (я не хочу, чтобы оно имело значение по умолчанию или было равно нулю).

Я заметил, что подготовленное заявление, которое оно сгенерировало, не включает столбец, хотя я дал ему значение.

вот моя модель аудита:

 @Entity @Table(name = "audit_trail") public class AuditTrail {  @Id  @GeneratedValue(strategy = GenerationType.IDENTITY)  @Column(name = "id", nullable = false)  private Long id;   @Column(name = "changed_msg", nullable = false, length = 1000)  private String changed_msg;   @MapsId  @ManyToOne  @JoinColumn(name="changed_by", nullable = false)  private User changed_by;   @MapsId  @ManyToOne  @JoinColumn(name="person_id", nullable = false)  private People personId;   @Column(name="when_occured", nullable = false, length = 100)  private Date when;     public AuditTrail() {  }  //plus accessors }  

и вот метод, который я вызываю, используя postman для тестирования:

 @PostMapping("/people/{id}/audittrail")  @ResponseBody  public ResponseEntitylt;AuditTrailgt; addAudit(@PathVariable("id") long personId, @RequestBody Maplt;String, Stringgt; requestBody, @RequestHeader("Authorization") String headers){  AuditTrail auditTrail = new AuditTrail();  People person= peopleRepository.findById(personId).get();  if (headers != null) {  if (sessionRepository.findByToken(headers).isPresent()) {  if (requestBody.containsKey("changed_msg")) {  auditTrail.setChanged_msg(requestBody.get("changed_msg"));  auditTrail.setPersonId(person);  Session user = sessionRepository.findByToken(headers).get();  SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss");  Date date = new Date(System.currentTimeMillis());  auditTrail.setWhen(date);  auditTrail.setChanged_by(user.getUser());  // as a note above is where i'm setting the changed by, below I printed the user val out and it gave me the user value that i expected.  System.out.println("User: " user.getUser());  AuditTrail temp = new AuditTrail();  try {  temp = auditTrailRepository.save(auditTrail);  }catch (Exception e){  e.printStackTrace();  }  return new ResponseEntitylt;gt;(temp, HttpStatus.valueOf(200));  }  else  return new ResponseEntitylt;gt;(auditTrail, HttpStatus.valueOf(400));  }  else  return new ResponseEntitylt;gt;(auditTrail, HttpStatus.valueOf(401));  }  else  return new ResponseEntitylt;gt;(auditTrail, HttpStatus.valueOf(401));  }  

вот 2 части, которые я отметил из трассировки стека:

 Hibernate: insert into audit_trail (changed_msg, when_occured, person_id) values (?, ?, ?)  
 Caused by: java.sql.SQLException: Field 'changed_by' doesn't have a default value  

Я пытаюсь понять, как заставить его добавить «changed_by» в сгенерированный подготовленный оператор, поскольку он отсутствует.

вот полный маршрут стека:

 Hibernate: insert into audit_trail (changed_msg, when_occured, person_id) values (?, ?, ?) 2021-12-03 23:46:05.667 WARN 15452 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1364, SQLState: HY000 2021-12-03 23:46:05.667 ERROR 15452 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : Field 'changed_by' doesn't have a default value 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:331)  at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233)  at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:566)  at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743)  at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711)  at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654)  at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:407)  at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)  at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)  at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)  at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)  at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)  at com.sun.proxy.$Proxy112.save(Unknown Source)  at springboot.services.PeopleControllerHibernate.addAudit(PeopleControllerHibernate.java:188)  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  at java.base/java.lang.reflect.Method.invoke(Method.java:566)  at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)  at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)  at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)  at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)  at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)  at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)  at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)  at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)  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:681)  at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)  at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)  at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)  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:189)  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)  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:189)  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)  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:189)  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)  at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)  at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)  at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)  at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)  at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1722)  at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)  at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)  at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)  at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)  at java.base/java.lang.Thread.run(Thread.java:834) Caused by: org.hibernate.exception.GenericJDBCException: could not execute statement  at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)  at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)  at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)  at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200)  at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3298)  at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3825)  at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:107)  at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)  at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478)  at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)  at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475)  at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:344)  at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40)  at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:99)  at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1362)  at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:453)  at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3212)  at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2380)  at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:448)  at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183)  at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40)  at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281)  at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)  at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:562)  ... 65 more Caused by: java.sql.SQLException: Field 'changed_by' doesn't have a default value  at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)  at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)  at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)  at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)  at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092)  at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1040)  at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1340)  at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1025)  at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)  at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)  at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)  ... 85 more  

Комментарии:

1. Каково значение user.getUser() в строке auditTrail.setChanged_by(user.getUser()); ?

2. он выводит имя пользователя ragnar (тестовый пользователь). получено с помощью идентификатора сеанса для захвата пользователя, у которого есть этот идентификатор сеанса.

3. В коде, который вы опубликовали, не должно быть этой проблемы.