使用多对多关系映射只读数据库而不使用连接表

时间:2011-12-23 13:19:20

标签: java hibernate jpa

我有一个类似于@ManyToMany without join table (legacy database)的问题,还有一个问题。

我有两张表AB

  • A,其中包含多列主键(IDID2
  • B,其中包含多列主键(IDID3

A中的行可以引用BB.ID = A.ID)中的多行,而B中的行可以引用A中的多行。

编辑:数据库是一个我无法更改的只读旧数据库。我不需要映射与JPA的关系(我可以在我的程序逻辑中使用额外的选择来做它)但是它会很好。

它基本上是没有连接表的多对多关系。因为,对于链接的问题,我只需阅读表格,我尝试在两个类中使用两个一对多的关系。

我遇到的另一个问题是用于连接的ID都不是主键。

我有以下课程:

@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引用AA.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。类AB都是简化(匿名)的示例。

2 个答案:

答案 0 :(得分:4)

您可以创建一个充当连接表的视图:

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

然后将它作为ManyToMany映射到JPA中,并将AJOINB作为连接表。

如果A.ID2和B.ID3本身是唯一的,您甚至不需要在JPA bean中映射A.ID和B.ID。

答案 1 :(得分:2)

你可以分享一些表中的样本记录吗?

问题非常明显。对于任何一对多的关系,在“一”方面,应该只有一个可以唯一识别的记录。在这里,我认为,因为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.id和B.id将A映射到B,那么这变为一对多,其中A(100)可以引用B(100,101),因为id为1000

我认为这样可行。但是如果你必须使用相同的列(如问题中所述)从B映射到A,它将不起作用,因为一方(B)有重复。

我能正确理解你的问题吗?