[英]Hibernate OneToMany mapping & Query generation : More than one row with the given identifier was found
我正在使用 spring-boot-starter-data-jpa 1.5.1.RELEASE 內部使用 hibernate-core 5.0.11.Final
我的實體看起來像這樣:
區域Dto
@Entity
@Table(name = "AREA")
@EntityListeners(AuditingEntityListener.class)
public class AreaDto {
@Id
@Column(name = "AREA_ROWID")
private String areaRowId;
@OneToMany(cascade = CascadeType.DETACH)
@JoinColumn(name = "AREA_ROWID")
private Collection<FestivalDto> festival;
@OneToMany(cascade = CascadeType.DETACH, mappedBy = "area")
private Collection<ActionDto> actions;
@OneToMany(fetch = FetchType.LAZY)
@JoinTable(name = "FESTIVAL", joinColumns = {
@JoinColumn(name = "AREA_ROWID", referencedColumnName = "AREA_ROWID")}, inverseJoinColumns = {
@JoinColumn(name = "FESTIVAL_ROWID", referencedColumnName = "FESTIVAL_ROWID")})
private Collection<ActionDto> festivalActions;
}
音樂節
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "FESTIVAL")
public class FestivalDto {
@Id
@Column(name = "FESTIVAL_ROWID")
@GeneratedValue(generator = "FESTIVAL_ROWID_SEQ")
private Long festivalRowId;
@ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY, optional = true)
@JoinColumn(name = "AREA_ROWID")
private AreaDto area;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "festival")
private Collection<ActionDto> actions = Lists.newArrayList();
}
行動Dto
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "ACTION")
public class ActionDto implements Serializable {
...
@Id
@Column(name = "ACTION_ID")
@GeneratedValue(generator = "ACTION_ID_SEQ")
private Long actionId;
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
@ManyToOne(cascade = DETACH, fetch = FetchType.LAZY)
@JoinColumn(name = "FESTIVAL_ROWID")
private FestivalDto festival;
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
@ManyToOne(cascade = DETACH, fetch = FetchType.LAZY)
@JoinColumn(name = "AREA_ROWID")
private AreaDto area;
}
我試圖理解以下想法:
hibernate 使用什么策略來決定用於獲取所有相關操作的festival_rowid(或festival_row id)? 如果我更改 LAZY 和 EAGER 之間的 FestivalActions 獲取策略,休眠生成的 SQL 查詢將如何變化? 我知道代理、集合代理等等,我的問題是特定於這些 sql 是如何生成的,以及它如何對決定綁定參數的值產生影響。
我的映射是否准確,或者我應該為這種關系使用多地圖,因為一個地區可能有多個節日,每個節日可能有多個動作
背景:如果我將獲取類型從 LAZY 更改為 EAGER,我會遇到以下錯誤。 希望了解行為以獲得對修復的一些信心。 我已閱讀SO和錯誤
org.hibernate.HibernateException: More than one row with the given identifier was found: data.dto.ActionDto@280856b5
這種映射沒有多大意義。 您不能以這種方式映射festivalActions
因為無法通過這種映射正確地持久化狀態。 此外, AreaDto
festival
應該由FestivalDto
的area
映射。 請嘗試以下操作:
@Entity
@Table(name = "AREA")
@EntityListeners(AuditingEntityListener.class)
public class AreaDto {
@Id
@Column(name = "AREA_ROWID")
private String areaRowId;
@OneToMany(cascade = CascadeType.DETACH, mappedBy = "area")
private Collection<FestivalDto> festival;
@OneToMany(cascade = CascadeType.DETACH, mappedBy = "area")
private Collection<ActionDto> actions;
public Collection<ActionDto> getFestivalActions() {
return festival.stream().flatMap(f -> f.actions.stream()).collect(Collectors.toList());
}
}
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "FESTIVAL")
public class FestivalDto {
@Id
@Column(name = "FESTIVAL_ROWID")
@GeneratedValue(generator = "FESTIVAL_ROWID_SEQ")
private Long festivalRowId;
@ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY, optional = true)
@JoinColumn(name = "AREA_ROWID")
private AreaDto area;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "festival")
private Collection<ActionDto> actions = Lists.newArrayList();
}
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "ACTION")
public class ActionDto implements Serializable {
...
@Id
@Column(name = "ACTION_ID")
@GeneratedValue(generator = "ACTION_ID_SEQ")
private Long actionId;
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
@ManyToOne(cascade = DETACH, fetch = FetchType.LAZY)
@JoinColumn(name = "FESTIVAL_ROWID")
private FestivalDto festival;
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
@ManyToOne(cascade = DETACH, fetch = FetchType.LAZY)
@JoinColumn(name = "AREA_ROWID")
private AreaDto area;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.