尝试将正确的关系数据添加到一对多连接的另一端时,我遇到了此异常。
由于某些原因,它不会自动提取car_id
这是我的代码。
汽车型号
@Data
@Entity
@Table(uniqueConstraints={
@UniqueConstraint(columnNames = {"date", "auctionNumber", "auctionId"})
})
public class Car {
@Id
@GeneratedValue
private UUID id;
private String date;
private int auctionId;
private int auctionNumber;
@OneToMany(mappedBy = "car", orphanRemoval = true, cascade={CascadeType.ALL})
private List<CarPhoto> photos;
public void addPhoto(CarPhoto photo) {
if (photos == null) {
photos = new ArrayList<CarPhoto>();
}
photos.add(photo);
photo.setCar(this);
}
}
汽车照片模型
@Data
@Entity
@Table(name="car_photo")
public class CarPhoto {
@Id
@GeneratedValue
private UUID id;
@Column(unique=true)
private String path;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="car_id", insertable=false, updatable=false)
private Car car;
}
存储库 @资料库 公共接口CarRepository扩展了CrudRepository { }
持久性
...loop cardata {
Car car = new Car();
car.setAuctionId(cardata.auctionId);
car.setAuctionNumber(cardata.auctionNumber);
car.setDate(cardata.date);
Pattern.compile("#").splitAsStream(cardata.pictures).forEach(path - > {
CarPhoto photo = new CarPhoto();
photo.setPath(path);
car.addPhoto(photo);
});
cars.add(car);
}
carRepository.saveAll(cars);
错误日志
2019-02-24 21:16:32.086 WARN 52624 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 23502
2019-02-24 21:16:32.086 ERROR 52624 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: null value in column "car_id" violates not-null constraint
Detail: Failing row contains (cec6e570-7ce9-4094-bbc1-32bcd732c695, pictures, null).
2019-02-24 21:16:32.086 ERROR 52624 --- [nio-8080-exec-1] o.h.i.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement]
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [car_id]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:296)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:253)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:536)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:746)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:533)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:304)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy101.saveAll(Unknown Source)
at ivs.datacollection.GetCarHandler.endElement(GetCarHandler.java:121)
任何帮助将不胜感激。
更新
感谢您的所有宝贵建议。我已经按照@Andronicus的建议将我的Car模型更新为以下内容:
@Data
@Entity
@Table(uniqueConstraints={
@UniqueConstraint(columnNames = {"date", "auctionNumber", "auctionId"})
})
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
public class Car {
@Id
@GeneratedValue
private UUID id;
@EqualsAndHashCode.Include
private String date;
@EqualsAndHashCode.Include
private int auctionId;
@EqualsAndHashCode.Include
private int auctionNumber;
@OneToMany(mappedBy = "car", orphanRemoval = true, cascade={CascadeType.ALL})
private List<CarPhoto> photos;
public void addPhoto(CarPhoto photo) {
if (photos == null) {
photos = new ArrayList<CarPhoto>();
}
photos.add(photo);
photo.setCar(this);
}
}```
And CarPhoto model to:
```lang-java
@Data
@Entity
@Table(name="car_photo")
public class CarPhoto {
@Id
@GeneratedValue
private UUID id;
@Column(unique=true)
private String path;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="car_id")
private Car car;
}
我还在得到
Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "car_auction_id_auction_number_date_key"
Detail: Key (auction_id, auction_number, date)=(236, 50024, 2019-02-28) already exists.
所以我不确定休眠在哪里检查相等性,因为这肯定可以工作吗?
答案 0 :(得分:2)
实际上,您需要同时从映射中删除insertable = false
和updatable = false
:
@JoinColumn(name="car_id", insertable=false, updatable=false)
并为equals
和hashCode
实体覆盖Car
和CarPhoto
方法,以避免重复实体。您可以使用龙目岛的@EqualsAndHashCode(callSuper = false)
来做到这一点。
因为只有insertable=true
才可以插入实体,但这会违反唯一约束。
答案 1 :(得分:1)
从声明insertable=false
中删除@JoinColumn(name="car_id", insertable=false, updatable=false)
。因为现在您拒绝设置和更新字段car_id