Monday, March 5, 2018

In Hibernate HQL, how do I left join fetch a subclass' linked entities when multiple subclasses have a property with the same name?

Leave a Comment

Summary

In Hibernate, I am trying to LEFT JOIN FETCH properties from subclasses of a main class, where multiple subclasses have properties with the same name. Hibernate, though, is only fetching the first subclass' linked entities, and not the others.

Background

I am modelling genomic features (genes, transcripts and exons) and genetic variants in a Hibernate-based system. Genes, Transcripts and Exons are all subclasses of GenomicFeature, and Variants can each have zero-to-many GenomicFeatures. Genes, in turn, have zero-to-many transcripts -- as do Exons -- and Transcripts have zero-to-many Genes and Exons. Each of these relationships are fetched lazily. Sometimes, though, I want to fetch a variant and all of its genomic features, as well as all of the genomic features linked from the immediate genomic features. Eg, I want to fetch a specific variant, the Genes/Transcripts/Exons associated with the variant, all the Transcripts of the genes, all the Genes&Exons of the Transcripts, and all the Transcripts of the Exons.

The problem

When I do a query for the above, it works except that the Transcripts for the Genes are not fetched, only the Exon's Transcripts are fetched. I assume this is because the property -- gene.transcripts and exon.transcripts -- shares the same name.

What I've tried

The main query, in a PagingAndSortingRepository, is below

    @Query("SELECT v FROM Variant v"         + " LEFT JOIN FETCH v.variantGenomicFeatures AS vgf"         + " LEFT JOIN FETCH vgf.genomicFeature AS gf LEFT JOIN FETCH gf.genes LEFT JOIN FETCH gf.exons LEFT JOIN FETCH gf.transcripts"         + " WHERE"         + "     v.id = (:id)") public Variant findOneByIdAndGenomicFeaturesEagerly(@Param("id") Integer id); 

I've tried joining genomicFeature twice, once for Genes and once for Transcripts&Exons, but this doesn't work.

I've tried only selecting Genes (WHERE TYPE(gf) = Gene), but looking at the query it generates, it still joins only the Exon's Transcripts and then returns the Genes.

2 Answers

Answers 1

I figured it out. It just works. I had a syntax error in my HQL.

When a discriminated subclass has properties/column that are not in the root class all properties of all distriminator subclasses are accessible in the HQL when using the root class in the FROM statement.

Answers 2

I didn't try myself but maybe with alias on fetch clause can help Hibernate to distinguish field ?

LEFT JOIN FETCH gf.genes as g  LEFT JOIN FETCH gf.exons as e  LEFT JOIN FETCH gf.transcripts as t 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment