Quantcast
Channel: Active questions tagged rest - Stack Overflow
Viewing all articles
Browse latest Browse all 3641

Why is JPA query so slow?

$
0
0

I am implementing queries in my web application with JPA repositories. The two main tables I am querying from are FmReportTb and SpecimenTb.

Here are the two entity classes (only important attributes are listed).

//FmReportTb.java@Entity@Table(name="FM_REPORT_TB")public class FmReportTb implements Serializable {    @Column(name="ROW_ID")    private long rowId;    @Column(name="FR_BLOCK_ID")    private String frBlockId;    @Column(name="FR_FULL_NAME")    private String frFullName;    @OneToOne    @JoinColumn(name="SPECIMEN_ID")    private SpecimenTb specimenTb;

FmReportTb has OneToOne relationship with SpecimenTb.

@Entity@Table(name="SPECIMEN_TB")public class SpecimenTb implements Serializable {    private String mrn;    @OneToOne(mappedBy="specimenTb", cascade=CascadeType.ALL)    private FmReportTb fmReportTb;

The query I am working on is to find all records in FmReportTb and show a few attributes from FmReportTb plus mrn from SpecimenTb. Here is my JPA repository for FmReportTb:

@Repositorypublic interface FmReportRepository extends JpaRepository<FmReportTb, Long> {    @Query("select f from FmReportTb f where f.deleteTs is not null")    public List<FmReportTb> findAllFmReports();

Since, I am only showing part of the attributes from FmReportTb and one attribute from SpecimenTb, I decided to create a Value Object for FmReportTb. The constructor of the VO class assigns attributes from FmReportTb and grabs mrn attribute from SpecimenTb based on the OneToOne relationship. Another reason for using VO is because table FmReportTb has a lot of OneToMany children entities. For this particular query, I don't need any of them.

public class FmReportVO {    private String frBlockId;    private Date frCollectionDate;    private String frCopiedPhysician;    private String frDiagnosis;    private String frFacilityName;    private String frFullName;    private String frReportId;    private String filepath;    private String mrn;    public FmReportVO(FmReportTb fmReport) {        this.frBlockId = fmReport.getFrBlockId();        this.frCollectionDate = fmReport.getFrCollectionDate();        this.frCopiedPhysician = fmReport.getFrCopiedPhysician();        this.frDiagnosis = fmReport.getFrDiagnosis();        this.frFacilityName = fmReport.getFrFacilityName();        this.frFullName = fmReport.getFrFullName();        this.frReportId = fmReport.getFrReportId();        this.mrn = fmReport.getSpecimenTb().getMrn();    }

I implemented findall method in servicebean class to return a list of FmReportTb VOs.

//FmReportServiceBean.java    @Override    public List<FmReportVO> findAllFmReports() {        List<FmReportTb> reports = fmReportRepository.findAllFmReports();        if (reports == null) {            return null;        }        List<FmReportVO> fmReports = new ArrayList<FmReportVO>();        for (FmReportTb report : reports) {            FmReportVO reportVo = new FmReportVO(report);            String filepath = fileLoadRepository.findUriByFileLoadId(report.getFileLoadId().longValue());            reportVo.setFilepath(filepath);            fmReports.add(reportVo);        }        return fmReports;    }

Lastly, my controller looks like this:

@RequestMapping(        value = "/ristore/foundation/",        method = RequestMethod.GET,        produces = "application/json")public ResponseEntity<List<FmReportVO>> getAllFmReports() {    List<FmReportVO> reports = ristoreService.findAllFmReports();    if (reports == null) {        return new ResponseEntity<List<FmReportVO>>(HttpStatus.NOT_FOUND);    }    return new ResponseEntity<List<FmReportVO>>(reports, HttpStatus.OK);}

There are about 200 records in the database. Surprisingly, it took almost 2 full seconds to retrieve all the records in JSON. Even though I did not index all the tables, this is way too slow. Similar query takes about probably a few ms on the database directly. Is it because I am using Value Objects or JPA query tends to be this slow?

EDIT 1This may have to do with the fact that FmReportTb has almost 20 OneToMany entities. Although the fetchmode of these child entities are set to LAZY, JPA Data repository tends to ignore the fetchmode. So I ended up using NamedEntityGraph to specify the attributes EAGER. This next section is added to the head of my FmReportTb entity class.

@Entity@NamedEntityGraph(        name = "FmReportGraph",         attributeNodes = {           @NamedAttributeNode("fileLoadId"),          @NamedAttributeNode("frBlockId"),          @NamedAttributeNode("frCollectionDate"),          @NamedAttributeNode("frDiagnosis"),          @NamedAttributeNode("frFullName"),          @NamedAttributeNode("frReportId"),          @NamedAttributeNode("specimenTb")})@Table(name="FM_REPORT_TB")

And then @EntityGraph("FmReportGraph") was added before the JPA repository query to find all records. After doing that, the performance is improved a little bit. Now fetching 1500 records only takes about 10 seconds. However, it still seems too slow given each json object is fairly small.


Viewing all articles
Browse latest Browse all 3641

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>