簡體   English   中英

Hibernate OneToMany 映射和查詢生成:找到具有給定標識符的不止一行

[英]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;


}

我試圖理解以下想法:

  1. hibernate 使用什么策略來決定用於獲取所有相關操作的festival_rowid(或festival_row id)? 如果我更改 LAZY 和 EAGER 之間的 FestivalActions 獲取策略,休眠生成的 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應該由FestivalDtoarea映射。 請嘗試以下操作:

@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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM