【问题标题】:Many to many association without join table没有连接表的多对多关联
【发布时间】:2014-09-20 18:51:58
【问题描述】:

我想在以下(简化的)数据库中应用 JPA:

NODE                         AUTHORITY
-----                        ----------
idNode int                   idAuthorities int
nameNode varchar(50)         person varchar(255)
idAuthorities int            rank int
PRIMARY KEY (idNode)         PRIMARY KEY (idAuthorities, rank)
FOREIGN KEY (idAuthorites)

所以一个节点可以有多个权限,一个权限可以被多个节点引用。

我希望我的课程看起来像:

@Entity
@Table(name="NODE")
public class Node {

    private Integer id;
    private String nameNode;
    private Set<Authority> authorities;

    // ... getter and setter normaly annoted for "id" and "nameNode"

    @ManyToMany
    public Set<Authority> getAuthorities(){
        return authorities;
    }
    // ... setter ...

}

@Entity
@Table(name="AUTHORITY")
public class Authority {

    private AuthorityPK pk;
    private String person;
    privat Set<Node> nodes;

    // ... getter and setter normaly annoted for "person"

    @Id
    public AuthorityPK getPk(){
        return this.pk
    }
    // ... setter ...

    @ManyToMany
    public Set<Node> getNodes(){
        return nodes;
    }
    // ... setter ...

}

@Embeddable
public class AuthorityPK implements Serializable {
    private Integer idAuthorities;
    private Integer rankAuthorities;

    // override of equals and hashCode
}

但是注释“@ManyToMany”似乎只能与“@JoinTable”一起使用,在这种情况下(据我所知)它是不可用的。 有谁知道除了修改数据库之外是否还有其他方法?

【问题讨论】:

  • 你描述的不是多对多关系,而是“节点”和“权限”之间的多对一关系。许多“节点”可以具有相同的(一个)“权限”。从来没有任何“节点”超过一个“权威”。我有一种感觉,你的类名“节点”和“权威”被错误地选择了。这些类的每个实例似乎都代表了人们通常所说的一个“节点”或“权威”。
  • 没错,班级的名字是精心挑选的。但是“Nodes”类的一个条目可以引用多个“Authorities”,因为它们中的任意数量都可以具有相同的字段“idAuthority”(主键是“rankAuthority”和“idAuthority”的组合)
  • JPA 不允许这样做,因为它需要外键来引用完整的主键以用于标识目的。您需要查看 JPA 之外的提供程序特定代码才能使其正常工作。

标签: java sql hibernate jpa jpa-2.0


【解决方案1】:

JPA 不允许这样做,因为它需要外键来引用完整的主键以用于标识目的,并且它可能不适用于缓存。如果可以的话,我建议使用使用实际主键的关系表切换到更传统的模型。

如果您的提供程序允许映射部分 pks(我相信 Hibernate 会这样做),您要做的是制作两个 1:M 映射,每个映射使用 JoinColumn 而不是 JoinTable,但将 Node->Authority 上的映射标记为 insertable=false,可更新=假

例如:

public class Node {
    @Id
    private Integer id;
    private String nameNode;
    @OneToMany
    @JoinColumn(name = "idAuthorites", referencedColumnName = "idAuthorites", insertable=false, updatable=false)
    private Set<Authority> authorities;
    ...

public class Authority {
    @Id
    private AuthorityPK pk;
    private String person;
    @OneToMany
    @JoinColumn(name = "idAuthorites", referencedColumnName = "idAuthorites")
    private Set<Node> nodes;
    ...

【讨论】:

    猜你喜欢
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    • 2016-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-13
    • 1970-01-01
    相关资源
    最近更新 更多