ach
ach

Reputation: 6234

Additional "outer" join columns on a JPA entity relationship through a join table

I have two entities that are related through a join table, modeled with JPA like so:

class EntityA {

  @ManyToMany
  @JoinTable(name="joining_entity",
    joinColumns={@JoinColumn(name="entity_a_id", referencedColumnName="id")},
    inverseJoinColumns={@JoinColumn(name="entity_b_id", referencedColumnName="id")}
  )
  List<EntityB> entityBList;

  Long importantIdentifier;

}

class EntityB {

  @ManyToMany(mappedBy="entityBList")
  List<EntityA> entityAList;

  Long importantIdentifier;

}

This works fine for a simple many-to-many relationship, but in my case I also need to join only when importantIdentifier matches in both entities.

With an ad-hoc query this is simply a matter of adding an ON clause to the join: AND entity_a.important_identifier=entity_b.important_identifier

However I am struggling to model this with JPA/Hibernate annotations. I've tried:

I am not married to using @JoinTable if there's another way to achieve this, i.e. some method using a third concrete entity representing the join table.

Upvotes: 0

Views: 305

Answers (1)

Stephen
Stephen

Reputation: 1058

This modeling will give you the flexibility you need. Model a third entity called relationalAB and change models EntityA and EntityB from @ManyToMany to @OneToMany. In your new relationalAB model I would have two @ManytoOne mappings for EntityA and EntityB:` Example:

@Entity
@Table(name = "RELATIONAL_A_B")
public class relationalAB {

    @Id
    @GeneratedValue
    @Column(name="RELATIONAL_A_B_ID")
    protected Integer id;


    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "enitityA_id", insertable = false, updatable = false)
    protected EntityA entityA;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "enitityB_id", insertable = false, updatable = false)
    protected EntityB entityB;
    ...

@Entity
@Table(name = "ENTITY_A")
public class EntityA {

    @Id
    @GeneratedValue
    @Column(name="ENTITY_A_ID")
    protected Integer id;


    @OneToMany(mappedBy = "entityA", cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    List<relationalAB> weakEnityList;

    ...

@Entity
@Table(name = "ENTITY_B")
public class EntityB {

    @Id
    @GeneratedValue
    @Column(name="ENTITY_B_ID")
    protected Integer id;

    @OneToMany(mappedBy = "entityB", cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    List<relationalAB> weakEnityList;

    ...`

Upvotes: 2

Related Questions