Mahmoud Saleh
Mahmoud Saleh

Reputation: 33635

How to define @ManyToMany inside a generated entity

i have a generated table called employee, as a relation between two tables:

Person , MedicalCompany

and i was wondering how to make manyToMany relation between this generated table and another table, something like:

@ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "employee_role", joinColumns = { @JoinColumn(name = "employee_id") }, inverseJoinColumns = { @JoinColumn(name = "role_id") })
    private Set<Role> roles = new HashSet<Role>(0);

1- Generated Table:

@SuppressWarnings("serial")
@Entity
@Table(name = "employee")
@AssociationOverrides(value = {
        @AssociationOverride(name = "pk.medicalCompany", joinColumns = @JoinColumn(name = "company_id", referencedColumnName = "id")),
        @AssociationOverride(name = "pk.person", joinColumns = @JoinColumn(name = "employee_id", referencedColumnName = "person_id")),
        @AssociationOverride(name = "pk.titleText"),
        @AssociationOverride(name = "pk.employeeManager") })
public class Employee implements Serializable {

    @EmbeddedId
    private EmployeeCompanyId pk = new EmployeeCompanyId();

    @Transient
    public void setEmployeeManager(long employeeManager) {
        this.pk.setEmployeeManager(employeeManager);
    }

    public long getEmployeeManager() {
        return pk.getEmployeeManager();
    }

    @Transient
    public void setTitleText(String titleText) {
        this.pk.setTitleText(titleText);
    }

    public String getTitleText() {
        return pk.getTitleText();
    }

    public void setPerson(Person person) {
        this.pk.setPerson(person);
    }

    @Transient
    public Person getPerson() {
        return this.pk.getPerson();
    }

    public void setMedicalCompany(MedicalCompany medicalCompany) {
        this.pk.setMedicalCompany(medicalCompany);
    }

    @Transient
    public MedicalCompany getMedicalCompany() {
        return this.pk.getMedicalCompany();
    }

    public void setPk(EmployeeCompanyId pk) {
        this.pk = pk;
    }

    public EmployeeCompanyId getPk() {
        return pk;
    }

}

2- EmployeeCompanyId:

@SuppressWarnings("serial")
@Embeddable
public class EmployeeCompanyId implements Serializable {

    @ManyToOne
    private Person person;

    @ManyToOne
    private MedicalCompany medicalCompany;

    @Size(max = 150, message = "{long.value}")
    @Column(name = "title_text", length = 150, nullable = true)
    private String titleText;

    @Column(name = "employee_manager")
    private long employeeManager;

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public MedicalCompany getMedicalCompany() {
        return medicalCompany;
    }

    public void setMedicalCompany(MedicalCompany medicalCompany) {
        this.medicalCompany = medicalCompany;
    }

    public String getTitleText() {
        return titleText;
    }

    public void setTitleText(String titleText) {
        this.titleText = titleText;
    }

    public long getEmployeeManager() {
        return employeeManager;
    }

    public void setEmployeeManager(long employeeManager) {
        this.employeeManager = employeeManager;
    }

}

Upvotes: 1

Views: 931

Answers (1)

Piotr Nowicki
Piotr Nowicki

Reputation: 18224

You can't have relationships within @Embeddable which is an @EmbeddedId. You can have relationships only in regular @Embeddable.


JPA 2.0 FR spec, 11.1.15 EmbeddedId Annotation:

Relationship mappings defined within an embedded id class are not supported.

Hibernate 3.5 doc, 2.2.3.2.1. @EmbeddedId property

In the embedded id object, the association is represented as the identifier of the associated entity. But you can link its value to a regular association in the entity via the @MapsId annotation.


The least you can do is to use primary key types in embeddable. You can then map them to the entities in which the embeddable exist. In other words you can have something like:

@Embeddable
public class EmployeeCompanyId implements Serializable {

    private int personId;

    // ...
}

@Entity
public class Employee {

    @EmbeddedId
    private EmployeeCompanyId pk = new EmployeeCompanyId();

    @MapsId("personId")
    @ManyToOne
    private Person person;

    // ...
}

Upvotes: 1

Related Questions