Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

hibernate - JPA 2.0 many-to-many with extra column

I'm trying to do a ManyToMany relationship in JPA 2.0 (JBoss 7.1.1) with an extra column (in bold, below) in the relationship, like:

Employer           EmployerDeliveryAgent             DeliveryAgent
(id,...)   (employer_id, deliveryAgent_id, **ref**)  (id,...)

I wouldn't like to have duplicate attributes, so I would like to apply the second solution presented in http://giannigar.wordpress.com/2009/09/04/mapping-a-many-to-many-join-table-with-extra-column-using-jpa/ . But I can't get it to work, I get several errors like:

  1. Embedded ID class should not contain relationship mappings (in fact the spec says so);
  2. In attribute 'employerDeliveryAgent', the "mapped by" value 'pk.deliveryAgent' cannot be resolved to an attribute on the target entity;
  3. In attribute 'employerDeliveryAgent', the "mapped by" value 'pk.employer' cannot be resolved to an attribute on the target entity;
  4. Persistent type of override attribute "pk.deliveryAgent" cannot be resolved;
  5. Persistent type of override attribute "pk.employer" cannot be resolved;

Many people on that link said that it worked fine, so I suppose something is different in my environment, perhaps JPA or Hibernate version. So my question is: how do I achieve such scenario with JPA 2.0 (Jboss 7.1.1 / using Hibernate as JPA implementation)? And to complement that question: should I avoid using composite keys and instead use plain generated id and a unique constraint?

Thanks in advance.

Obs.: I didn't copy my source code here because it is essentially a copy of the one at the link above, just with different classes and attributes names, so I guess it is not necessary.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Both answers from Eric Lucio and Renan helped, but their use of the ids in the association table is redundant. You have both the associated entities and their ids in the class. This is not required. You can simply map the associated entity in the association class with the @Id on the associated entity field.

@Entity
public class Employer {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @OneToMany(mappedBy = "employer")
    private List<EmployerDeliveryAgent> deliveryAgentAssoc;

    // other properties and getters and setters
}

@Entity
public class DeliveryAgent {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @OneToMany(mappedBy = "deliveryAgent")
    private List<EmployerDeliveryAgent> employerAssoc;

    // other properties and getters and setters
}

The association class

@Entity
@Table(name = "employer_delivery_agent")
@IdClass(EmployerDeliveryAgentId.class)
public class EmployerDeliveryAgent {
    
    @Id
    @ManyToOne
    @JoinColumn(name = "employer_id", referencedColumnName = "id")
    private Employer employer;
    
    @Id
    @ManyToOne
    @JoinColumn(name = "delivery_agent_id", referencedColumnName = "id")
    private DeliveryAgent deliveryAgent;
    
    @Column(name = "is_project_lead")
    private boolean isProjectLead;
}

Still need the association PK class. Notice the field names should correspond exactly to the field names in the association class, but the types should be the type of the id in the associated type.

public class EmployerDeliveryAgentId implements Serializable {
    
    private int employer;
    private int deliveryAgent;

    // getters/setters and most importantly equals() and hashCode()
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...