IncidentHdr表与IncidentHdrDtl有一对多的映射。
IncidentHdr的实体类,这里将incidentDtls称为Lazy
@Entity
@Table(name="IR_TB_INCIDENT_HDR")
public class IncidentHdr implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(name="IR_TB_INCIDENT_HDR_INCIDENTID_GENERATOR", sequenceName="IR_SEQ_INCIDENT_ID")
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="IR_TB_INCIDENT_HDR_INCIDENTID_GENERATOR")
@Column(name="INCIDENT_ID")
private long incidentId;
@Column(name="ACTION_TAKEN")
private String actionTaken;
@NotFound(action=NotFoundAction.IGNORE)
@ManyToOne()
@JoinColumn(name = "CAT_CODE")
private CategoryMast categoryMast;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="CREATED_TIME")
private Date createdTime;
@Column(name="INCIDENT_SR_NO")
private String incidentSrNo;
@NotFound(action=NotFoundAction.IGNORE)
@ManyToOne()
@JoinColumn(name = "INCIDENT_STATUS")
private IncidentStatus incidentStatus;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="INCIDENT_TIME")
private Date incidentTime;
@NotFound(action=NotFoundAction.IGNORE)
@ManyToOne()
@JoinColumn(name = "LOCATION")
private LocationMast locationMast;
@NotFound(action=NotFoundAction.IGNORE)
@ManyToOne()
@JoinColumn(name = "SUB_CAT_CODE")
private SubCategoryMast subCategoryMast;
@OneToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE, CascadeType.REMOVE}, fetch = FetchType.LAZY, mappedBy="incidentHdr")
private Set<IncidentDtl> incidentDtls;
public IncidentHdr() {
}
}
事件详细信息的实体类。
@Entity
@Table(name="IR_TB_INCIDENT_DTL")
public class IncidentDtl implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(name="IR_TB_INCIDENT_DTL_MESSAGEID_GENERATOR", sequenceName="IR_SEQ_MESSAGE_ID")
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="IR_TB_INCIDENT_DTL_MESSAGEID_GENERATOR")
@Column(name="MESSAGE_ID")
private long messageId;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="ENTRY_TIME")
private Date entryTime;
@Column(name="ENTRY_USER")
private Long entryUser;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="INCIDENT_ID")
private IncidentHdr incidentHdr;
@Column(name="MSG_DESC")
private String msgDesc;
@Column(name="MSG_TYPE")
private String msgType;
public IncidentDtl() {
}
}
自定义repo类,它将具有初始选择查询(GET_INCIDENT_DETAILS)。 将根据输入dto追加新条件,并在此处形成完整查询。
public class IncidentReportingRepoCustomImpl implements IncidentReportingRepoCustom{
private static final MohLogger logger = MohLogFactory.getLoggerInstance(IncidentReportingRepoCustomImpl.class.getName());
@PersistenceContext
private EntityManager em;
@Override
public PaginationDto fetchIncidents(IncidentHdrSearchDto incidentHdrSearchDto) throws BusinessException {
PaginationDto inPaginationDto = new PaginationDto();
List<IncidentHdr> incidentHdrs = null;
StringBuilder query = null;
try{
query = new StringBuilder();
query.append(ReposJPQL.GET_INCIDENT_DETAILS);
Map<String, Object> parameters = new HashMap<String, Object>();
List<String> criteria = new ArrayList<String>();
createIncidentSearchQuery(parameters,criteria, incidentHdrSearchDto);
//append the query criteria
if (criteria.size() > 0) {
for (int i = 0; i < criteria.size(); i++) {
query.append(" AND ");
query.append(criteria.get(i));
}
}
Query q = em.createQuery(query.toString());
//logger.info("@@@@@@@@@@@@@@ QUERY @@@@@@@@@@@@@@ "+ query.toString());
//set parameters
for (Entry<String, Object> entry : parameters.entrySet()) {
q.setParameter(entry.getKey(), entry.getValue());
}
inPaginationDto.setTotalRecords(q.getResultList().size());
//pagination
if(inPaginationDto.getTotalRecords() > incidentHdrSearchDto.getMaxResult() && incidentHdrSearchDto.getFirstResult() != null && incidentHdrSearchDto.getMaxResult() != null){
q.setFirstResult(incidentHdrSearchDto.getFirstResult());
q.setMaxResults(incidentHdrSearchDto.getMaxResult());
}
incidentHdrs = q.getResultList();
}catch(IllegalArgumentException | IllegalStateException | DataAccessException | EntityNotFoundException e){
logger.error(e.getMessage());
throw new BusinessException(e);
}
inPaginationDto.setPaginatedList(incidentHdrs);
return inPaginationDto;
}
/**
* To generate query for incident search
* @param parameters
* @param criteria
* @param incidentHdrDto
*/
private void createIncidentSearchQuery(Map<String, Object> parameters, List<String> criteria, IncidentHdrSearchDto incidentHdrSearchDto) {
if(incidentHdrSearchDto.getIncidentSrNo() != null) {
criteria.add("upper(inc.incidentSrNo) like :incidentSrNo");
parameters.put("incidentSrNo" ,"%"+ incidentHdrSearchDto.getIncidentSrNo().toUpperCase()+"%");
}
if(incidentHdrSearchDto.getCategoryMast() != null) {
criteria.add("inc.categoryMast.catCode = :catCode");
parameters.put("catCode", incidentHdrSearchDto.getCategoryMast().getCatCode());
}
if(incidentHdrSearchDto.getLocationMast() != null) {
criteria.add("inc.locationMast.locCode = :location");
parameters.put("location", incidentHdrSearchDto.getLocationMast().getLocCode());
}
if(incidentHdrSearchDto.getPatientId() != null) {
criteria.add("inc.patientId = :patientId");
parameters.put("patientId", incidentHdrSearchDto.getPatientId());
}
if(incidentHdrSearchDto.getAmsWorkOrderNo() != null) {
criteria.add("inc.amsWorkOrderNo = :amsWorkOrderNo");
parameters.put("amsWorkOrderNo", incidentHdrSearchDto.getAmsWorkOrderNo());
}
if(incidentHdrSearchDto.getTypeMast() != null){
criteria.add("cm.typeCode = :typeCode");
parameters.put("typeCode", incidentHdrSearchDto.getTypeMast().getTypeCode());
}
if(incidentHdrSearchDto.getSentinelYn() != null){
if(incidentHdrSearchDto.getSentinelYn()){
criteria.add("inc.sentinelYn = :sentinelYn");
parameters.put("sentinelYn", "Y");
}else{
criteria.add("inc.sentinelYn = :sentinelYn");
parameters.put("sentinelYn", "N");
}
}
//get incidents which are reported with in 'x' hours.
if(incidentHdrSearchDto.getReportedWithIn() != null){
criteria.add(" (24 *(inc.createdTime - inc.incidentTime )) <= :withInHours");
parameters.put("withInHours", incidentHdrSearchDto.getReportedWithIn());
}
//severity based search, data need to fetch from the view.
if(incidentHdrSearchDto.getSeverityCode() != null){
criteria.add("inc.categoryMast.catCode IN ("+ReposJPQL.GET_CAT_SEVERITY+")"
+ " OR inc.subCategoryMast.subCatCode IN ("+ReposJPQL.GET_SUB_CAT_SEVERITY+")");
parameters.put("severityCode", incidentHdrSearchDto.getSeverityCode());
}
}
}
初始选择查询详细信息,
GET_INCIDENT_DETAILS = public String GET_INCIDENT_DETAILS = "SELECT inc FROM IncidentHdr inc LEFT JOIN inc.categoryMast cm LEFT JOIN inc.subCategoryMast sub LEFT OUTER JOIN inc.incidentDtls WHERE 1 = 1" ;
遇到IncidentHdr和IncidentDtl的N + 1问题。