[英]DataIntegrityViolationException persisting one to many relation
Boot,Jpa and hibernate to persist a one-many relation between venues and events. Boot,Jpa和冬眠使场地和事件之间保持一对多的关系。
The error i'm retrieving is 我正在检索的错误是
org.h2.jdbc.JdbcSQLException: NULL not allowed for column "VENUE_LOCATION"; SQL statement:
insert into event (id, date, description, media_ref, num_ratings, performer, performer_media, title, total_rating) values (null, ?, ?, ?, ?, ?, ?, ?, ?) [23502-192]
I've tried saving the parent(Venue) class first and exclusively but that produces the same error. 我试过先排它地保存parent(Venue)类,但这会产生相同的错误。
Venue 会场
public class Venue
{
@Id
private String name;
@Id
private String location;
@OneToOne(mappedBy = "venue",cascade = CascadeType.ALL)
@JoinColumn(name="id")
private VenueUser venueUser;
private String mediaRef;
private int rating;
@OneToMany(fetch=FetchType.LAZY,mappedBy = "venue",cascade = CascadeType.ALL)
private Set<Event> events;
//Constructors getters and setters below
Event 事件
@Entity
public class Event
{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
private String title;
private String description;
private String performer;
private String[] performerMedia;
private Calendar[] date;
@Transient
private double avgRating;
private int numRatings;
private int totalRating;
private String mediaRef;
@MapsId("name")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumns({
@JoinColumn(name="Venue_name",referencedColumnName = "name"),
@JoinColumn(name="venue_location",referencedColumnName = "location")
})
private Venue venue;
//Constructors getters and setters below
Controller 控制者
@RequestMapping(value = "/event",method=RequestMethod.POST)
public ResponseEntity addEvent(@RequestBody Event event)
{
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String name = auth.getName(); //get logged in username
Venue venue = userVenueRepository.findByEmail(name).getVenue();
event.setVenue(venue);
venue.addEvent(event);
if(eventRepository.saveAndFlush(event).equals(event)&&venueRepository.saveAndFlush(venue).equals(venue))
{
return new ResponseEntity(HttpStatus.CREATED);
}
else
{
return new ResponseEntity(HttpStatus.CONFLICT);
}
}
insert into event (id, date, description, media_ref, num_ratings, performer, performer_media, title, total_rating) values (null, ?, ?, ?, ?, ?, ?, ?, ?)
You need to set id to your Event entity. 您需要将ID设置为您的事件实体。 Better use @GeneratedValue
annotation with AUTO
, like here https://github.com/spring-projects/spring-data-jpa/blob/master/src/main/java/org/springframework/data/jpa/domain/AbstractPersistable.java 最好将@GeneratedValue
注释与AUTO
,例如https://github.com/spring-projects/spring-data-jpa/blob/master/src/main/java/org/springframework/data/jpa/domain/AbstractPersistable。爪哇
or use class AbstractPersistable as parent entity. 或使用类AbstractPersistable作为父实体。
Error says that location
field of Venue entity is null which cannot be as it is primary key. 错误说地点实体的location
字段为空,不能为空,因为它是主键。
You have two options for persisting Event object. 您有两个用于持久保存Event对象的选项。
cascade = CascadeType.PERSIST
in Event Entity and then save child entity. 如果要一次同时保留父项和子项,则可以在事件实体中指定cascade = CascadeType.PERSIST
,然后保存子项。 好的,所以我设法解决了这个问题,事后我不应该盲目地按照教程进行操作,也不知道@MapsId做了什么,所以我删除了它,一切都开始起作用了。这引起了将不胜感激的问题。
this way you don't need to add parent entry inside child object. 这样,您无需在子对象内添加父项 。
Remove mappedBy form Venue
entity 从表单Venue
实体中移除
Then add below code inside the Venue
entity before Set<Event>
然后在Set<Event>
之前在Venue
实体内添加以下代码
@JoinColumns({
@JoinColumn(name="Venue_name",referencedColumnName = "name"),
@JoinColumn(name="venue_location",referencedColumnName = "location")
})
Remove @JoinColumns
and @MapsId
from Event
entity 从Event
实体中删除@JoinColumns
和@MapsId
Then you don't need to write 那你就不用写了
event.setVenue(venue);
Hope it helps. 希望能帮助到你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.