我有下一个实体:
public class Delivery {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "delivery_seq")
@SequenceGenerator(
name = "delivery_seq",
sequenceName = "delivery_sequence",
allocationSize = 1)
private Long id;
@OneToMany(fetch = FetchType.EAGER,
cascade = {CascadeType.ALL},
orphanRemoval = true)
@JoinColumn(name = "delivery_id")
private Set<DeliveryItem> items = new HashSet<>();
}
@Entity
@Table(name = "delivery_status_history")
public class DeliveryStatusHistory {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "history_of_delivery_status_seq")
@SequenceGenerator(
name = "history_of_delivery_status_seq",
sequenceName = "history_of_delivery_status_sequence",
allocationSize = 1)
private Long id;
@Column(name = "delivery_status")
@Enumerated(EnumType.STRING)
private DeliveryStatusEnum status;
@JoinColumn(name = "delivery_id", referencedColumnName = "id")
@ManyToOne
private Delivery delivery;
}
Delivery
和DeliveryStatusHistory
具有更多的字段,但是Delivery
的DeliveryStatusHistory
没有OneToMany。DeliveryStatusHistory
与Delivery
具有ManyToOne关系。 DeliveryStatusHistory中的Delivery
属性非空。当我尝试更新
items
的内容时,出于某些原因,Hibernate尝试删除DeliveryStatusHistory
中的链接delivery.getItems().clear();
delivery.getItems.addAll(deliveryItems);
deliveryRepository.saveAndFlush(delivery);
错误:
2019-10-07 12:06:42.623 WARN 1 --- [ scheduling-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 23502
2019-10-07 12:06:42.623 ERROR 1 --- [ scheduling-1] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: null value in column "delivery_id" violates not-null constraint
Detail: Failing row contains (2558, 86, null, null, APPROVED, 2019-10-07 06:15:45.80725+00).
Where: SQL statement "UPDATE ONLY "public"."delivery_status_history" SET "delivery_id" = NULL WHERE $1 OPERATOR(pg_catalog.=) "delivery_id""
2019-10-07 12:06:42.623 INFO 1 --- [ scheduling-1] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
2019-10-07 12:06:42.627 ERROR 1 --- [ scheduling-1] o.s.s.s.TaskUtils$LoggingErrorHandler : Unexpected error occurred in scheduled task
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [delivery_id]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:297) ~[spring-orm-5.2.0.RC2.jar:5.2.0.RC2]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:254) ~[spring-orm-5.2.0.RC2.jar:5.2.0.RC2]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528) ~[spring-orm-5.2.0.RC2.jar:5.2.0.RC2]
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) ~[spring-tx-5.2.0.RC2.jar:5.2.0.RC2]
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242) ~[spring-tx-5.2.0.RC2.jar:5.2.0.RC2]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153) ~[spring-tx-5.2.0.RC2.jar:5.2.0.RC2]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.0.RC2.jar:5.2.0.RC2]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:178) ~[spring-data-jpa-2.2.0.RC3.jar:2.2.0.RC3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.0.RC2.jar:5.2.0.RC2]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) ~[spring-aop-5.2.0.RC2.jar:5.2.0.RC2]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.0.RC2.jar:5.2.0.RC2]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.0.RC2.jar:5.2.0.RC2]
at com.sun.proxy.$Proxy134.saveAndFlush(Unknown Source) ~[na:na]
at tech.lmru.cdsdrbridge.adeo.BDOUpdateService.updateDeliveryItems(BDOUpdateService.java:394) ~[classes/:1.4.0-RELEASE]
at sun.reflect.GeneratedMethodAccessor167.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_212]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_212]
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84) ~[spring-context-5.2.0.RC2.jar:5.2.0.RC2]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-5.2.0.RC2.jar:5.2.0.RC2]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_212]
有任何想法吗?
最佳答案
您可能需要更改DeliveryItems的级联类型。我会给CascadeType.PERSIST一个机会。这样,当您清除项目时,不会破坏对DeliveryStatusHistory的引用。
CascadeType.PERSIST : cascade type presist means that save() or persist() operations cascade to related entities.
CascadeType.MERGE : cascade type merge means that related entities are merged when the owning entity is merged.
CascadeType.REFRESH : cascade type refresh does the same thing for the refresh() operation.
CascadeType.REMOVE : cascade type remove removes all related entities association with this setting when the owning entity is deleted.
CascadeType.DETACH : cascade type detach detaches all related entities if a “manual detach” occurs.
CascadeType.ALL : cascade type all is shorthand for all of the above cascade operations.` (ref: https://howtodoinjava.com/hibernate/hibernate-jpa-cascade-types/)