休眠一对多映射和查询生成:找到具有给定标识符的多行



我正在使用 spring-boot-starter-data-jpa 1.5.1.RELEASE,它在内部使用休眠核心 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;

}

节日Dto

@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();
}

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;

}

我试图理解以下想法:

  1. hibernate使用什么策略来决定用于获取所有相关操作的festival_rowid(或festival_row ID)?如果我在 LAZY 和 EAGER 之间更改节日操作获取策略,休眠生成的 SQL 查询将如何变化?我知道代理,集合代理等等,我的问题特定于这些sql是如何生成的,以及它如何影响决定绑定参数的值。

  2. 我的地图是否准确,或者我应该为这种关系使用多重地图,因为一个区域可以有多个节日,每个节日可以有多个动作

背景: 我得到以下错误,如果我将获取类型从 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;

}

最新更新