I have a one-to-one relationship between a Media entitiy object and a MediaAnalysis , where the Media object is an abstract base class:
News Report Object
@Entity @DiscriminatorValue("N") public class NewsReport extends Media { @Column(name = "BODY", nullable = false) private String body; NewsReport(){} public NewsReport(String title, String link, String author, String body) { super(title, link, author); this.body= body; } public String getBody() { return body; } }
Media object
@Entity @Inheritance( strategy = InheritanceType.SINGLE_TABLE ) @DiscriminatorColumn(name = "TYPE", length = 1, discriminatorType = DiscriminatorType.STRING) public abstract class Media { @Id @GeneratedValue(strategy= GenerationType.AUTO) private Long id; @Column(name = "TITLE", nullable = false) private String title; @Column(name = "LINK", length = 500, nullable = false) private String link; @Column(name = "AUTHOR", length = 45, nullable = false) private String author; @OneToOne(mappedBy = "media") private MediaAnalysis analysis; Media(){} public Media(String title, String link, String author) { this.title = title; this.link = link; this.author = author; }
Media analysis
@Entity public class MediaAnalysis { @Id @GeneratedValue(strategy= GenerationType.AUTO) private Long id; @Column(name = "SUCCESS", nullable = false) private Boolean success; @OneToOne @JoinColumn( name = "MED_ID", nullable = false, foreignKey = @ForeignKey(name="MEA_MED_FK") ) private Media media; @Column(name = "CONTENT", nullable = false) private String content; MediaAnalysis() { } public MediaAnalysis(Media media, Boolean success, String content) { this.media = media; this.success = success; this.content = content; }
Now that I want to use my AnalysisRepository.getByMedia(..a NewsReport...)
public interface AnalysisRepository extends JpaRepository<MediaAnalysis,Long> { @Query("SELECT a FROM MediaAnalysis a LEFT JOIN FETCH a.media WHERE a.media = ?1") Optional<MediaAnalysis> getByMedia(Media media); }
To find MediaAnalysis on a NewsReport , for example, I would expect hibernate to start a single SELECT query, for example:
SELECT m. * from media analysis m, where m.med_id =?
But instead, when I turn on query logging, I see 2:
DEBUG ohSQL: 92 - select mediaanaly0_.id as id1_0_0_, media1_.id as id2_1_1_, mediaanaly0_.med_id as med_id3_0_0_, mediaanaly0_.success as success2_0_0_, media1_.author as author3_1_1_1, media__1_1_1_1 link_1_1_1_1 link_1_1_1_1_1_1_1 body as body6_1_1_, media1_.type as type1_1_1_ from mea_media_analysis mediaanaly0_ left external join med_media media1_ on mediaanaly0_.med_id = media1_.id where mediaanaly0_.med_id =?
TRACE ohtdsBasicBinder: 65 - binding parameter [1] as [BIGINT] - [1]
DEBUG ohSQL: 92 - select mediaanaly0_.id as id1_0_1_, mediaanaly0_.med_id as med_id3_0_1_, mediaanaly0_.success as success2_0_1_, media1_.id as id2_1_0_, media1_.author as author3_1_0_1, media1__1_1_1_1_1 link_1_1_1_1_1_1_l body as body6_1_0_, media1_.type as type1_1_0_ from mea_media_analysis mediaanaly0_ internal join med_media media1_ on mediaanaly0_.med_id = media1_.id where mediaanaly0_.med_id =?
TRACE ohtdsBasicBinder: 65 - binding parameter [1] as [BIGINT] - [1]
It seems to select MediaAnalysis first as expected, but then there is another query that seems unnecessary. The only difference I can tell between these two queries is the type of connection. I assume the problem is with Media inheritance.
Why is this happening? + What can I do to make sure this is a single request?
In the future, if I delete @Query from my repository, there are actually three queries!
DEBUG ohSQL: 92 - select mediaanaly0_.id as id1_0_, mediaanaly0_.med_id as med_id3_0_, mediaanaly0_.success as success2_0_ from mea_media_analysis mediaanaly0_ left external join med_media media1_ on mediaanaly0_.med_id = media1_.id where media1__id
TRACE ohtdsBasicBinder: 65 - binding parameter [1] as [BIGINT] - [1]
DEBUG ohSQL: 92 - select how media0_.id id2_1_0_, media0_.author how author3_1_0_, media0_.link how link4_1_0_, media0_.title how title5_1_0_, media0_.body how body6_1_0_, media0_.type how type1_1_0_, mediaanaly1_.id as id1_0_1_, mediaanaly1_. med_id as med_id3_0_1_, mediaanaly1_.success as success2_0_1_ from med_media media0_ left external join mea_media_analysis mediaanaly1_ to media0_.id = mediaanaly1_.med_id where media0_.id =?
TRACE ohtdsBasicBinder: 65 - binding parameter [1] as [BIGINT] - [1]
DEBUG ohSQL: 92 - select mediaanaly0_.id as id1_0_1_, mediaanaly0_.med_id as med_id3_0_1_, mediaanaly0_.success as success2_0_1_, media1_.id as id2_1_0_, media1_.author as author3_1_0_1, media1__1_1_1_1_1 link_1_1_1_1_1_1_l body as body6_1_0_, media1_.type as type1_1_0_ from mea_media_analysis mediaanaly0_ internal join med_media media1_ on mediaanaly0_.med_id = media1_.id where mediaanaly0_.med_id =?
TRACE ohtdsBasicBinder: 65 - binding parameter [1] as [BIGINT] - [1]