JPA single table inheritance mapping with additional join condition

27 Views Asked by At

enter image description here

As you can see from the above 'image' table definition there can be images owned by CATEGORY,DIVISION and few other entities. And, the JPA mapping are as follows:

@Entity
@Inheritance(strategy = SINGLE_TABLE)
@Table(name = "image")
@DiscriminatorColumn(name = "owning_entity", discriminatorType = STRING)
public class Image extends BaseEntity {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id")
    protected Long id;

    @Column(name = "img_key")
    protected UUID key;
  
    ...
}
@Entity
@DiscriminatorValue("DIVISION")
public class DivisionImage extends Image {

    @ManyToOne
    @JoinColumn(name = "owning_entity_id")
    private Division division;

...
}
@Entity
@Table(name = "division")
public class Division extends BaseEntity {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id")
    private Long id;

 
    @OneToMany(mappedBy = "division", cascade = ALL, orphanRemoval = true)
    private List<DivisionImage> images = new ArrayList<>();
...
}

My issue is that when loading the entity Division whose primary key is 3, the relationship division.images is also loading CATEGORY's images. Note that there 2 rows in the 'image' table where owning_entity_id is 3.

Is there a way to specify additional filter on the JoinColumn in Division, like so:

    @ManyToOne
    @JoinColumn(name = "owning_entity_id")
    @Where(clause="owning_entity='DIVISION'")  // <-- Apparently this does not work
    private Division division;

so that the right images are picked?

2

There are 2 best solutions below

0
Keerthi On

The @Where should be on the other side of the relationship :facepalm:

    @OneToMany(mappedBy = "division", cascade = ALL, orphanRemoval = true)
    @Where(clause="owning_entity='DIVISION'")
    private List<DivisionImage> images = new ArrayList<>();
2
Rakesh Chauhan On

you must use WhereJoinTable like below:

@WhereJoinTable(clause = "owning_entity ='DIVISION'")