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?
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;
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With