I have been getting this exception when trying to add the correct relationship data to the other side of the one to many join.
For some reason it is not picking up the car_id automatically
Here is my code.
Car model
@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);
}
}
Car Photo Model
@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;
}
Repository @Repository public interface CarRepository extends CrudRepository { }
Persistence
...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);
Error Logs
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)
Any help would be appreciated.
Update
Thanks for all your great advice. I have updated my Car model as suggested by @Andronicus to the following:
@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;
}
I am still getting
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.
So I am unsure where hibernate is checking for equality as surely this should work?
Actually you need to remove both insertable = false
and updatable = false
from your mapping:
@JoinColumn(name="car_id", insertable=false, updatable=false)
And override equals
and hashCode
methods for Car
and CarPhoto
entities to avoid duplicating entities. You can do this using lombok's @EqualsAndHashCode(callSuper = false)
.
Because with only insertable=true
you will be able to insert the entity, but this can violate unique constraint.
Remove insertable=false
from your declaration @JoinColumn(name="car_id", insertable=false, updatable=false)
. Because now you decline both set and update for field car_id
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.