问题描述
我正在使用spring-boot-starter-data-jpa 1.5.1.RELEASE,该内部使用hibernate-core 5.0.11.Final
我的实体看起来像这样:
AreaDto
@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;
}
FestivalDto
@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,mappedBy = "festival")
private Collection<ActionDto> actions = Lists.newArrayList();
}
ActionDto
@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;
}
我正在尝试理解以下想法:
-
冬眠用来决定用于获取所有相关动作的Festival_rowid(或Festival_row ID)的策略是什么?如果我在LAZY和EAGER之间更改festivalActions提取策略,休眠生成的SQL查询将如何变化?我了解代理,集合代理以及所有其他方面,我的问题是特定于这些sql的生成方式以及它对决定bind参数值的影响。
-
我的地图绘制是否准确,或者我应该为此关系使用多图,因为一个地区可能有多个节日,每个节日可能有多个动作
背景: 如果将提取类型从LAZY更改为EAGER,我将得到错误消失的提示。希望了解这种行为,以便对修复程序有一定的信心。我已阅读SO和error
org.hibernate.HibernateException: More than one row with the given identifier was found: data.dto.ActionDto@280856b5
解决方法
此映射没有太大意义。您无法以这种方式映射festivalActions
,因为无法通过这种映射正确地保持状态。 festival
中的AreaDto
也应由area
中的FestivalDto
映射。请尝试以下操作:
@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,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;
}