javaopenjpa

Fetch only 1 level in a OneToOne relation with same table


I searched on the web but cannot filter out the solution. I get pointed to Spring and Hibernate but I am only interested in the solution with OpenJPA.

I have a table in which I store the taxonomy tree. The key is the TAXON_ID and it is linked with its parent through the PARENT_ID. I created the following DTO named TaxonDto (I left out the fields that are of no importance):

@Column(name="PARENT_ID")
private Long      parentId;
@Column(name="RANG", length=3, nullable=false)
private String    rang;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="TAXON_ID", nullable=false, unique=true, updatable=false)
private Long      taxonId;

@OneToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY, targetEntity=TaxonDto.class, orphanRemoval=true)
@JoinColumn(name="PARENT_ID", referencedColumnName="TAXON_ID", updatable=false, insertable=false)
private TaxonDto  parent;

My problem lies in the @OneToOne. I did a test with FetchType.EAGER but then the size of the returned data is 3x bigger as with FetchType.LAZY since I get all parents below the taxon. What I want is that the parent is fetched when the rang is a specific value namely oso. I can live with a solution where the parent is not recursively filled, the parent of the parent should not be returned.

Is this possible and if so how can I do this? I have seen discriminators, fetchgroup and subclass DTO but it leaves me clueless.


Solution

  • In the entity class you can implement a method annotated with @PostLoad. Check the rang and load parent if relevant.

    Like this:

    private TaxonDto getPostLoadTaxon() {
      return parent;
    }
    
    @PostLoad
    private void onPostLoad() {
      if (getRang().equals("oso")) {
        getPostLoadTaxon();
      }
    }