繁体   English   中英

父复合键的 JPA 注释作为子复合主键的一部分

[英]JPA annotation for parent composite key to be part of child composite primary key

我试图绘制一个有多个比赛的比赛日,但无法弄清楚注释。

我想最终得到的是这样的(这是一个简化的例子):

TABLE: race_day
    date (PK)
    venue (PK)
    description

TABLE: race
    date (PK but also FK on race_day table)
    venue (PK but also FK on race_day table)
    race_number (PK)
    description

到目前为止,我已经提出了以下 POJO + 注释:

public class RaceDayPK implements Serializable {

    @Column(name="race_date")
    private String raceDate;
    @Column(name="venue")
    private String venue;
...
}

public class RaceDay {

    @EmbeddedId
    private RaceDayPK raceDayPk;

    @OneToMany(mappedBy = "raceDay", orphanRemoval = true, cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
    private final List<Race> races = new ArrayList<>();

...
}

public class Race {

    @ManyToOne
    @JoinColumns({
        @JoinColumn(name = "race_date", referencedColumnName = "race_date"),
        @JoinColumn(name = "venue", referencedColumnName = "venue")
    })
    private RaceDay raceDay;

    private int raceNumber;
    private String raceTitle;
...
}

如何使用 RaceDay 连接列和 RaceNumber 为 Race 制作 EmbeddedId(我猜这就是我需要的)? 任何帮助表示赞赏。 我在 StackOverflow 上看到了数十个 JoinColumn 示例和 EmbeddedId 示例,但似乎没有一个以我需要的方式将两者结合起来。

经过一些黑客攻击,我我让它像这样工作。 注意 OneToMany 注释的 mappingBy 参数中嵌套的“racePk.raceMeeting”:

public class RaceDayPK implements Serializable {

    @Column(name="race_date")
    private String raceDate;
    @Column(name="venue")
    private String venue;
...
}


public class RaceDay {

    @EmbeddedId
    private RaceDayPK raceDayPk;

    @OneToMany(mappedBy = "racePk.raceDay", orphanRemoval = true, cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
    private final List<Race> races = new ArrayList<>();

...
}


public class RacePk implements Serializable {

    @ManyToOne
    @JoinColumns({
        @JoinColumn(name = "race_date", referencedColumnName = "race_date"),
        @JoinColumn(name = "venue", referencedColumnName = "venue")
    })
    private RaceDay raceDay;
    @Column(name = "race_number")
    private int raceNumber;
...
}


public class Race {

    @EmbeddedId
    private final RacePk racePk = new RacePk();
    private String raceTitle;
...
}

尚不知道这是否会在某个时候失败,但 MySQL 表似乎已正确自动生成。

TABLE: race_day
        id(PK)
        date (PK)
        venue (PK)
        description

TABLE: race
        id(PK but also FK on race_day table)
        date (PK but also FK on race_day table)
        venue (PK but also FK on race_day table)
        race_number (PK)
        description

对于上面给出的表,我能够生成序列并使用以下代码将数据保留在表中的约束之后。

    public class RaceDayPK implements Serializable {

        private Long id;
        private String raceDate;
        private String venue;
    ...
    }

    @Entity
    @IdClass(RaceDayPK.class)
    public class RaceDay {

        @Id
        @Column(name="id")
        @GeneratedValue(strategy=GenerationType.SEQUENCE,generator = "R_SEQ")
        @SequenceGenerator(sequenceName = "RD_SEQ", allocationSize = 1, name = "R_SEQ")
        private Long id;

        @Id
        @Column(name="race_date")
        private String raceDate;

        @Id
        @Column(name="venue")
        private String venue;

        @OneToMany(mappedBy = "raceDay", cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
        private Set<Race> races;

    ...
    }

    public class RacePK implements Serializable {


        private RaceDay raceDay;
        private int raceNumber;
    ...
    }

    @Entity
    @IdClass(RacePK.class)
    public class Race {

        @Id
        @ManyToOne(cascade = CascadeType.ALL)
        @JoinColumns({
            @JoinColumn(name = "race_date", referencedColumnName = "race_date"),
            @JoinColumn(name = "venue", referencedColumnName = "venue"),
            @JoinColumn(name = "id", referencedColumnName = "id")
        })
        @JsonIgnore
        private RaceDay raceDay;

        @Id
        private int raceNumber;

        private String raceTitle;
    ...
    }

dao 代码需要更改如下。

public RaceDay saveRaceDay(RaceDay raceDay){
 if(raceDay.getRaces()!=null){
            raceDay.getRaces().forEach(race ->{
                race.setRaceDay(raceDay);
            });
        }
        }

不确定它是否有效,但试试这个方法:

public class RacePK implements Serializable {

    private RaceDayPK raceDay;    
    private String raceNumber;
...
}

@Entity
@IdClass(RacePK.class)
public class Race {

    @Id 
    @ManyToOne...
    private RaceDay raceDay;

    @Id
    private int raceNumber;
    private String raceTitle;
...
}

请注意,PK 字段名称应与@id-annotaed 字段名称完全相同。 Google for Derived identifiers 以了解更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM