冗余列 - 具有复合ID的一对一映射

时间:2016-07-11 11:18:51

标签: hibernate jpa spring-data-jpa

这是我的模特

@Entity
public class Picture {

    @EmbeddedId
    private PictureId id;

    ...   
}

@Embeddable
public class PictureId implements Serializable {
    private static final long serialVersionUID = -8285116986358642545L;

    @Column(nullable = false, name = "GALLERY_ID") private long galleryId;
    @Column(nullable = false, name = "AUTHOR_ID") private long authorId;
    @Column(nullable = false, name = "ORDINAL_NUMBER") private int ordinalNumber;

    ...   
}

@Entity
public class Gallery {

    @Id
    @GeneratedValue
    private long id;
    private String name;

    @OneToOne
    @JoinColumns({
            @JoinColumn(name = "REDUNDANT_GALLERY_ID", referencedColumnName = "GALLERY_ID"),
            @JoinColumn(name = "COVER_AUTHOR_ID", referencedColumnName = "AUTHOR_ID"),
            @JoinColumn(name = "COVER_ORDINAL_NUMBER", referencedColumnName = "ORDINAL_NUMBER")
    })
    private Picture cover;

    ...
}

我想在这里指定@JoinColums没有必要,但我想让它更清楚。使用此模型,在GALLERY表中创建了一个冗余列,该列反映了ID的值。我想摆脱这个专栏。字段cover可能为空。

在考虑了很多之后,我决定将这个映射更好地移动到外部表。显然它没有解决我的问题而且变得更加复杂。

@Entity
public class Gallery {

    @OneToOne
    @JoinTable(name = "GALLERY_COVER",
        joinColumns = {
                @JoinColumn(name = "GALLERY_ID", referencedColumnName = "ID")
        },
        inverseJoinColumns = {
                @JoinColumn(name = "REDUNDANT_GALLERY_ID", referencedColumnName = "GALLERY_ID"),
                @JoinColumn(name = "AUTHOR_ID", referencedColumnName = "AUTHOR_ID"),
                @JoinColumn(name = "ORDINAL_NUMBER", referencedColumnName = "ORDINAL_NUMBER")
    })
    private Picture cover;
}

我试图使用@AssociationOverride@AttributeOverride,但我失败了。你能帮我解决这些问题吗?

编辑:这是一个repository的模型

1 个答案:

答案 0 :(得分:0)

Forget the join table and the redundant column name. It's OK to use the same column name twice in one Entity as long as only one instance of it can be inserted/updated. The @Column and @JoinColumn annotations let you override the default insertable/updatable values.

@Entity
public class Gallery {

    @Id
    @GeneratedValue
    private long id;
    private String name;

    @OneToOne
    @JoinColumns({
            // no new column name here, just specify insertable/updatable
            @JoinColumn(name = "GALLERY_ID", insertable=false, updatable=false),
            @JoinColumn(name = "COVER_AUTHOR_ID", referencedColumnName = "AUTHOR_ID", insertable=false, updatable=false),
            @JoinColumn(name = "COVER_ORDINAL_NUMBER", referencedColumnName = "ORDINAL_NUMBER", insertable=false, updatable=false)
    })
    private Picture cover;

    ...
}

The cleaner approach, however, would be to change the primary key on Picture so it doesn't include the galleryId. If authorId and ordinalNumber already specify a unique key, just remove galleryId from the join.