Отображение базы данных только для чтения с отношением «многие ко многим» без таблицы соединений - PullRequest
12 голосов
/ 23 декабря 2011

У меня есть вопрос, похожий на @ ManyToMany без таблицы соединений (устаревшая база данных) с дополнительной проблемой.

У меня есть две таблицы A и B

  • A с первичным ключом из нескольких столбцов (ID и ID2)
  • B с первичным ключом из нескольких столбцов (ID и ID3)

Строка в A может ссылаться на несколько строк в B (B.ID = A.ID), а на строку в B могут ссылаться несколько строк в A.

EDIT : база данных является устаревшей базой данных только для чтения, которую я не могу изменить.Мне не нужно отображать отношения с JPA (я мог бы просто сделать это в своей программной логике с дополнительными выборами), но было бы неплохо.

Это в основном отношения многие ко многим без таблицы соединений,Поскольку, что касается связанного вопроса, мне просто нужно прочитать таблицы, я попытался с двумя отношениями один-ко-многим в обоих классах.

Дополнительная проблема, которую я имею, состоит в том, что оба ID s использовалидля объединения не первичный ключ.

У меня есть следующие классы:

@Entity
@Table( name = "A" )
@IdClass( PrimaryKeysA.class )
public class A {

    @Id
    @Column( name = "ID", insertable = false, updatable = false, columnDefinition = "char" )
    private String id;

    @Id
    @Column( name = "ID2", insertable = false, updatable = false )
    private int id2;

    @OneToMany( cascade = CascadeType.ALL )
    @JoinColumn( name = "ID", columnDefinition = "char", referencedColumnName = "ID" )
    private Set< B > setOfBs;

}

@Entity
@Table( name = "B" )
@IdClass( PrimaryKeysB.class )
public class B {

    @Id
    @Column( name = "ID", insertable = false, updatable = false, columnDefinition = "char" )
    private String id;

    @Id
    @Column( name = "ID3", insertable = false, updatable = false )
    private int id3;

    @OneToMany( cascade = CascadeType.ALL )
    @JoinColumn( name = "ID", columnDefinition = "char", referencedColumnName = "ID" )
    private Set< A > setOfAs;

}

Hibernate генерирует следующую ошибку:

Exception while preparing the app : referencedColumnNames(ID) of package.B referencing package.A not mapped to a single property

Я не оченьполучить сообщение: B.id ссылается на одно свойство в A (A.id).

РЕДАКТИРОВАТЬ: по запросу:

public class PrimaryKeysA implements Serializable {

private static final long   serialVersionUID    = 1L;

private int    id1;
private int    id2;

    // getters/setters/equals/hashcode

}

PrimaryKeysB аналогично id3 вместоиз id2.Оба класса A и B являются упрощенными (анонимными) примерами.

Ответы [ 2 ]

4 голосов
/ 03 января 2012

Вы можете создать представление, которое будет действовать как таблица соединения:

CREATE VIEW AJOINB AS
SELECT A.ID as AID, A.ID2 as AID2, B.ID as BID, B.ID3 as BID3
FROM A JOIN B ON A.ID = B.ID

И затем отобразить его в JPA как ManyToMany с таблицей соединения AJOINB.B.ID3 сами по себе уникальны, вам даже не нужно отображать A.ID и B.ID в ваших бобах JPA.

2 голосов
/ 29 декабря 2011

Можете ли вы поделиться некоторыми примерами записей из ваших таблиц?

Проблема очень ясна.Для любого отношения «один-много» на стороне «один» должна быть только одна запись, которая может быть однозначно идентифицирована.Здесь, я думаю, поскольку id не уникален, есть несколько записей.

Вы можете попробовать использовать @JoinColumns и добавить оба столбца, чтобы однозначно идентифицировать сущность на стороне «one».

@OneToMany
@JoinColumns({
    @JoinColumn(name="yourID1", referencedColumnName="yourID1"),
    @JoinColumn(name="yourid2", referencedColumnName="yourid2")
})

Я предполагаю, что у вас есть следующие данные.

таблица A:

id2    c1          id
100    content1    1000
101    content2    1001

таблица B:

id3    s1          id
100    content1    1000
101    content2    1000
102    content3    1001
103    content4    1001

Здесь id2 и id3 являютсяуникальный.A.id уникален, а b.id - нет;типичный сценарий OneToMany.

Если я сопоставлю A с B, используя A.id и B.id, то это станет один ко многим, где A (100) может обозначать B (100, 101) какИдентификатор 1000

Я думаю, это будет хорошо работать.Но если вам нужно сопоставить B с A, используя те же столбцы (как указано в вопросе), это не сработает, поскольку одна сторона (B) имеет дубликаты.

Правильно ли я понимаю ваш вопрос?

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