Many to many association without join table

11,804

JPA does not allow this as it requires foreign keys to reference the full primary key for identity purposes, and it might not work well with caching. If you can, I would recommend switching to a more traditional model using a relation table that uses the actual primary keys.

If your provider allows mapping partial pks (I believe Hibernate does), what you would do is make two 1:M mappings each using a JoinColumn instead of JoinTable, but mark the one on Node->Authority as insertable=false, updatable=false

For example, something like:

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;
    ...
Share:
11,804
Admin
Author by

Admin

Updated on July 02, 2022

Comments

  • Admin
    Admin over 1 year

    I'd like to apply JPA in the following (simplified) database:

    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)
    

    So one node can have multiple authorities and one authority can be referenced by multiple nodes.

    And I wanted my classes to look like:

    @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
    }
    

    But the annotation "@ManyToMany" seems to be usable only with "@JoinTable", which isn't usable (as far as I understand) in that case. Does anyone know if there is a way arroud beside modifying the database?