JPA несколько ManyToOne с общим FK - PullRequest
0 голосов
/ 04 ноября 2018

У меня есть 2 сущности с составным PK, которые имеют один и тот же тип (в приведенном ниже примере это класс Shared ). Также у меня есть 1 сущность, которая создает связь между сущностями Foo и Bar. Вот пример:

@Entity
class Shared {
    @Id private Long id;
}


@Entity
class Foo {
    @EmbeddedId private FooPK id;
}

@Embeddable
class FooPK implements Serializable {
    @ManyToOne
    @JoinColumn(name="shared_id")
    private Shared shared;
    private Long fooId;
}

@Entity
class Bar {
    @EmbeddedId private BarPK id;
}

@Embeddable
class BarPK implements Serializable {
    @ManyToOne
    @JoinColumn(name="shared_id")
    private Shared shared;
    private Long barId;
}

@Entity
class FooVsBar {
    @EmbeddedId private FooVsBarPK id;
}

@Embeddable
class FooVsBarPK implements Serializable {
    @ManyToOne
    @JoinColumns({
        @JoinColumn(name="id_shared_foo", referencedColumnName="shared_id"),
        @JoinColumn(name="id_foo", referencedColumnName="foo_id"),
    })
    private Foo foo;

    @ManyToOne
    @JoinColumns({
        @JoinColumn(name="id_shared_bar", referencedColumnName="shared_id"),
        @JoinColumn(name="id_bar", referencedColumnName="bar_id"),
    })
    private Bar bar;
}

Таким образом, в таблице FooVsBar есть 4 столбца (2 FK), но я бы хотел получить 3 столбца: id_foo, id_bar и id_shared, так как Foo и Bar всегда будут связаны с то же самое Shared. Поэтому нет смысла повторять id_shared, оно всегда будет одинаковым.

UPDATE : Вот как выглядит база данных UML. К сожалению, я не могу изменить таблицы, мне просто нужно сопоставить JPA с этой моделью. enter image description here

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Наконец, решение было таким же, как в примере @Vlad Mihalcea. Вот полный код (методы получения и установки не указаны):

@Entity
public class Shared {
    @Id
    private Long id;
}

@Entity
public class Bar {
    @EmbeddedId
    private BarPK id;

    @MapsId("sharedId")
    @ManyToOne
    @JoinColumn(name="shared_id")
    private Shared shared;
}

@Embeddable
public class BarPK implements Serializable {
    private static final long serialVersionUID = 1L;

    @Column(name="shared_id")
    private Long sharedId;

    @Column(name="bar_id")
    private Long barId;
}

@Entity
public class Foo {
    @EmbeddedId
    private FooPK id;

    @MapsId("sharedId")
    @ManyToOne
    @JoinColumn(name="shared_id")
    private Shared shared;  
}

@Embeddable
public class FooPK implements Serializable {
    private static final long serialVersionUID = 1L;

    @Column(name="shared_id")
    private Long sharedId;

    @Column(name="foo_id")
    private Long fooId;
}

@Entity
public class FooVsBar {

    @EmbeddedId
    private FooVsBarPK id;

    @ManyToOne
    @JoinColumns({
        @JoinColumn(name="shared_id", referencedColumnName="shared_id", insertable=false, updatable=false),
        @JoinColumn(name="foo_id", referencedColumnName="foo_id", insertable=false, updatable=false)
    })
    private Foo foo;

    @ManyToOne
    @JoinColumns({
        @JoinColumn(name="shared_id", referencedColumnName="shared_id", insertable=false, updatable=false),
        @JoinColumn(name="bar_id", referencedColumnName="bar_id", insertable=false, updatable=false)
    })
    private Bar bar;
}

@Embeddable
public class FooVsBarPK implements Serializable {

    private static final long serialVersionUID = 1L;

    @Column(name="shared_id")
    private Long sharedId;

    @Column(name="foo_id")
    private Long fooId;

    @Column(name="bar_id")
    private Long barId;
}
0 голосов
/ 05 ноября 2018

Попробуй так:

@Entity
class FooVsBar {
    @EmbeddedId private FooVsBarPK id;

    @ManyToOne
    @JoinColumns({
        @JoinColumn(name="shared_id", referencedColumnName="shared_id", 
                    insertable=false, updatable=false),
        @JoinColumn(name="foo_id", referencedColumnName="foo_id",
                    insertable=false, updatable=false)
    })
    private Foo foo;

    @ManyToOne
    @JoinColumns({
        @JoinColumn(name="shared_id", referencedColumnName="shared_id",
                    insertable=false, updatable=false),
        @JoinColumn(name="bar_id", referencedColumnName="bar_id",
                    insertable=false, updatable=false)
    })
    private Bar bar;
}

@Embeddable
class FooVsBarPK implements Serializable {

    private Long sharedId;

    private Long fooId;

    private Long barId;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...