How to map dynamic query to projection interface. not an entity class - spring

#Entity
#Table(name = "delivery_status_summary", schema = "dsd")
#Data
public class DeliveryStatusSummaryV2 {
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="delivery_status_summary_id_seq")
#SequenceGenerator(name="delivery_status_summary_id_seq", sequenceName="delivery_status_summary_id_seq", allocationSize=1)
private Integer id;
#Column(name = "expected_delivery_date")
private LocalDateTime expectedDeliveryDate;
private Integer total;
#Column(name = "on_time")
private Integer onTime;
private Integer late;
private Integer pending;
#Column(name = "not_received")
private Integer notReceived;
}
Repository:
public interface DeliveryStatusSummaryRepository extends JpaRepository<DeliveryStatusSummary, Integer>, DeliveryStatusSummaryCustomRepository {
//language=SQL
String MANAGER_DELIVERY = "WITH dates AS (" +
" SELECT" +
" GENERATE_SERIES(" +
" CAST(:range_start AS TIMESTAMP)," +
" CAST(:range_end AS TIMESTAMP)," +
" INTERVAL '1 day'" +
" ) AS day" +
"), deliveries AS (" +
" SELECT *" +
" FROM dsd.delivery_status_summary AS dss" +
" WHERE dss.expected_delivery_date >= CAST(:range_start AS TIMESTAMP) AND" +
" dss.expected_delivery_date <= CAST(:range_end AS TIMESTAMP)" +
"), managers AS (" +
" SELECT *" +
" FROM dsd.teams as t" +
" WHERE t.manager_id IN (:manager_ids)" +
"), summary AS (" +
" SELECT t.manager_id," +
" dss.expected_delivery_date," +
" CAST(dss.expected_delivery_date AS DATE) AS day," +
" SUM(dss.total) AS total," +
" SUM(dss.on_time) AS on_time," +
" SUM(dss.late) AS late," +
" SUM(dss.pending) AS pending," +
" SUM(dss.not_received) AS not_received" +
" FROM deliveries AS dss" +
" INNER JOIN dsd.sla_datasets AS s ON dss.sla_id = s.sla_id" +
" INNER JOIN dsd.datasets AS ds ON ds.dataset_id = s.dataset_id" +
" INNER JOIN managers AS t on ds.team_id = t.ad_id" +
" INNER JOIN dsd.employee AS e on t.manager_id = e.id" +
" GROUP BY t.manager_id, dss.expected_delivery_date" +
")" +
"SELECT d.day AS expectedDeliveryDate, " +
"s.manager_id, " +
"COALESCE(s.total, 0) AS totalCount, " +
"COALESCE(s.on_time, 0) AS onTimeCount, " +
"COALESCE(s.late, 0) AS lateCount, " +
"COALESCE(s.pending, 0) AS pendingCount, " +
"COALESCE(s.not_received, 0) AS notReceivedCount " +
"FROM dates AS d " +
"LEFT JOIN summary AS s ON d.day = s.day " +
"ORDER BY s.manager_id, d.day";
#Query(value = MANAGER_DELIVERY, nativeQuery = true)
CompletableFuture<List<DeliveryStatusSummaryByManagerAndDate>> getDailyDeliveryStatusSummaryByManagers(
#Param("manager_ids") final Set<String> employeeIds,
#Param("range_start") ZonedDateTime rangeStart,
#Param("range_end") ZonedDateTime rangeEnd
);
}
Projection.
public interface DeliveryStatusSummaryByManagerAndDate {
String getManagerId();
LocalDate getExpectedDeliveryDate();
int getTotalCount();
int getOnTimeCount();
int getLateCount();
int getPendingCount();
int getNotReceivedCount();
}
getDailyDeliveryStatusSummaryByManagers works as expected.
But I need to have an opportunity to change group by section of this query on-the-fly, depending on user's input. So I decided to play with query as a plain string.
The idea is to put a query to string, and then depending on user's input, make query.replace('group placeholder', group by <needed list of fields>).
In order to archive this, I created a custom DeliveryStatusSummaryCustomRepository.
I decided not to make replace on a string so far, but to try to execute a simple query MANAGER_DELIVERY_QUERY.
public interface DeliveryStatusSummaryCustomRepository {
List<DeliveryStatusSummaryByManagerAndDate> getDailyDeliveryStatusSummaryByManagersV2();
}
#Repository
public class DeliveryStatusSummaryCustomRepositoryImpl implements DeliveryStatusSummaryCustomRepository {
private String MANAGER_DELIVERY_QUERY_TRY = "SELECT '1' AS managerId, " +
"CAST(dss.expected_delivery_date AS DATE) AS expectedDeliveryDate, " +
"0 AS totalCount, " +
"0 AS onTimeCount, " +
"0 AS lateCount, " +
"0 AS pendingCount, " +
"0 AS notReceivedCount " +
"FROM dsd.delivery_status_summary AS dss " +
"WHERE dss.expected_delivery_date >= CAST('01-01-2022' AS TIMESTAMP) AND dss.expected_delivery_date <= CAST('10-01-2022' AS TIMESTAMP)";
private final PrimaryDbConfig primaryDbConfig;
public DeliveryStatusSummaryCustomRepositoryImpl(PrimaryDbConfig primaryDbConfig) {
this.primaryDbConfig = primaryDbConfig;
}
#Override
public List<DeliveryStatusSummaryByManagerAndDate> getDailyDeliveryStatusSummaryByManagersV2() {
final LocalContainerEntityManagerFactoryBean em = primaryDbConfig.primaryEntityManager();
final EntityManager nativeEntityManager = em.createNativeEntityManager(new HashMap<>());
final Query query = nativeEntityManager.createQuery(MANAGER_DELIVERY_QUERY_TRY);
return query.getResultList();
}
}
But I got an error:
org.hibernate.hql.internal.ast.QuerySyntaxException: delivery_status_summary is not mapped
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:169)
at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:91)
at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:77)
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:333)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3765)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3654)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:737)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:593)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:330)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:278)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:276)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:192)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:113)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:73)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:162)
at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:613)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:725)
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:23)
at amp.ae.dataset.status.dashboard.library.repository.primary.DeliveryStatusSummaryCustomRepositoryImpl.getDailyDeliveryStatusSummaryByManagersV2(DeliveryStatusSummaryCustomRepositoryImpl.java:115)
at amp.ae.dataset.status.dashboard.library.repository.primary.DeliveryStatusSummaryCustomRepositoryImpl$$FastClassBySpringCGLIB$$f0397
I believe that the issue is related to DeliveryStatusSummaryByManagerAndDate is not entity, this is just projection.
If so, what approach to use for writing dynamic query taking into account that MANAGER_DELIVERY query is quite complicated to be re-written with Hibernate joins?
I heard about https://www.jooq.org.
Any advice appreciated.

You need to use EntityManager.createNativeQuery() method.
Also you can just autoware EntityManager
#Repository
public class DeliveryStatusSummaryCustomRepositoryImpl {
#PersistenceContext
private EntityManager entityManager;
}
To map query results to DTO
Replace the interface DeliveryStatusSummaryByManagerAndDate with POJO with getters and setters.
Use a result transformer from Hibernate
import org.hibernate.query.Query;
Query<DeliveryStatusSummaryByManagerAndDate> query = entityManager
.createNativeQuery(sql)
.unwrap(Query.class)
.setResultTransformer(
Transformers.aliasToBean(DeliveryStatusSummaryByManagerAndDate.class)
);
return query.getResultList();
Also check this mapping Hibernate query results to custom class?

Related

Spring Data Elastic Search with dynamic document replicas and shards

I'm using spring boot 2.4 and spring-data-elasticsearch 4.1. I have document like this
#Document(indexName = "test", replicas = 3, shards = 2)
public class TestDocument {
#Id
#Field(type = FieldType.Keyword)
private String Id;
#Field(type = FieldType.Object, enabled = false)
private String name;
...
getters
setters
}
And i want to override hardcoded values in replicas and shards in Document annotation from application.yml for index creation because this values can be differnet by environment of my service. Is there any way to do this?
You can disable auto-creation of an index by using
#Document(indexName = "test", createIndex = false)
and then create the index by using the IndexOperations.create(settings). The following code is taken from Spring Data Elasticsearch tests (https://github.com/spring-projects/spring-data-elasticsearch/blob/4.1.x/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java#L2361-L2384):
public void shouldCreateIndexWithGivenClassAndSettings() {
// given
String settings = "{\n" + " \"index\": {\n" + " \"number_of_shards\": \"1\",\n"
+ " \"number_of_replicas\": \"0\",\n" + " \"analysis\": {\n"
+ " \"analyzer\": {\n" + " \"emailAnalyzer\": {\n"
+ " \"type\": \"custom\",\n"
+ " \"tokenizer\": \"uax_url_email\"\n" + " }\n"
+ " }\n" + " }\n" + " }\n" + '}';
// when
indexOperations.delete();
indexOperations.create(parse(settings));
indexOperations.putMapping(SampleEntity.class);
indexOperations.refresh();
// then
Map<String, Object> map = indexOperations.getSettings();
assertThat(operations.indexOps(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)).exists()).isTrue();
assertThat(map.containsKey("index.number_of_replicas")).isTrue();
assertThat(map.containsKey("index.number_of_shards")).isTrue();
assertThat((String) map.get("index.number_of_replicas")).isEqualTo("0");
assertThat((String) map.get("index.number_of_shards")).isEqualTo("1");
}
Instead of parsing the JSON for the settings you should create a Document in your code:
Document settings = Document.create();
settings.put("index.number_of_replicas", 42);
settings.put("index.number_of_shards", 42);
you can Add a #Setting annotion to you Entity, which is provided by spring-data-elasticsearch, in order to help you custom index info .
https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearc.misc.index.settings

Database column data having linebreaks are ignored when retrieved from Hibernate?

A CLOB database column data has linebreaks :
When I retrieve it and display the data inside a html table cell then the linebreaks are ignored :
#Override
#Transactional
public String getPrevisionRessourceAutreForProduit(Objectif produit) {
String hql = "select to_char(r.ress_comment_1) " +
"from ressource r join type_ressource t on r.type_ress_code = t.type_ress_code " +
"left join objectif o on r.obj_code = o.obj_code " +
"where o.obj_code = " + produit.getCode().toString() + " and upper(t.type_ress_code) = 'AUT'";
Session sessionDynamic = Utils.createDynamicSession(env);
Query query = sessionDynamic.createSQLQuery(hql);
#SuppressWarnings("unchecked")
List<String> list = (List<String>) query.list();
sessionDynamic.close();
if (list.isEmpty())
return "";
else
return list.get(0) == null ? "" : list.get(0);
}
So how to fix it ?
I found the solution by enclosing the data inside the tags <pre>...</pre>

How can I make a HQL using Instant from java.time

I am developing a small project using spring-jpa. I decided to use java.time to deal with date problems. Everything was working fine until I had to deal with HQL.
So I am trying to make this query:
#Query("SELECT sensor "
+ "FROM TrashSensor sensor "
+ "join sensor.measurementList measurement "
+ "WHERE sensor.id = 100 AND measurement.instantOfMeasure > '2017-01-01'")
public TrashSensor findTrashSensorByIdCustom();
But the type of measurement.instantOfMeasure is a Instant from java.time.
So this last AND of my WHERE clause is always returning true so I don't get the filter I need.
How can I make this comparison using HQL and java.time? Does Hibernate support this??
You can develop it with
1 way -> (in TrashSensorRepository interface )
#Query("SELECT sensor "
+ "FROM TrashSensor sensor "
+ "join sensor.measurementList measurement "
+ "WHERE sensor.id =:sensorId AND measurement.instantOfMeasure > :instantOfMeasure")
public TrashSensor findTrashSensorByIdCustom(#Param("sensorId") sensorId, #Param("instantOfMeasure") Instant instantOfMeasure);
The types from the java.time package are directly mapped to corresponding SQL types(Since Java 8)
LocalDate is mapped to DATE
LocalTime and OffsetTime are mapped to TIME
Instant, LocalDateTime, OffsetDateTime and ZonedDateTime are mapped to TIMESTAMP
2 way -> (if you have created custom utility class for run HQL dynamically)
// Utility for run custom dynamic HQL query
#Service
#Transactional
public class HibernateQueryService {
private final Logger log = LoggerFactory.getLogger(HibernateQueryService.class);
private JpaContext jpaContext;
public List executeHibernateQuery(String sql, Class entity){
log.debug("HibernateQuery executing: "+sql);
Session session = jpaContext.getEntityManagerByManagedType(Article.class).unwrap(Session.class);
return session.createQuery(sql, entity).getResultList();
}
}
// Custom converter
public class CustomConverter{
public static Timestamp toTimestamp(Instant time){
return time != null ? Timestamp.from(time) : null;
}
public static Instant toInstant(Timestamp timestamp){
return timestamp != null ? timestamp.toInstant() : null;
}
}
// Solution
public class Solution2{
public static makeIt(){
boolean isFirst = true;
String query = "SELECT sensor "
+ "FROM TrashSensor sensor "
+ "join sensor.measurementList measurement ";
if(sensor.id != null){
query += isFirst ? "WHERE " : "AND ";
query += "sensor.id="+sensor.id+" ";
isFirst = false;
}
if(measurement.instantOfMeasure != null){
query += isFirst ? "WHERE " : "AND ";
query += "measurement.instantOfMeasure > "+toTimestamp(measurement.instantOfMeasure)+" ";
}
List<TrashSensor> hibernateQueryService.executeHibernateQuery(query, TrashSensor.class);
}
}

What's the most appropriate way to compare dates in this hibernate query?

I have a Spring MVC REST service that accepts two #RequestParams called from and to. These are parsed as java.util.Date and passed to the following method in my DAO class.
#Override
public List<ErrorsDTOEntity> getAllErrors(Date from, Date to) {
try {
Query query = getSession().createQuery(
"SELECT NEW com.mydomain.esb.jpa.dto.ErrorsDTOEntity(ee, ec.message) "
+ "FROM ErrorsEntity ee, EventCodeEntity ec "
+ "WHERE ee.responseTime > " + from.getTime() + " "
+ "AND ee.responseTime < " + to.getTime() + " "
+ "AND ee.serviceResponseCode = ec.code "
+ "GROUP BY ee.domainName, ee.serviceName, ec.message, ee.serviceErrorCount, ee.errorTimestamp, "
+ "ee.deviceName, ee.servErrId, ee.serviceResponseCode, ee.elapsedTime, ee.forwardTime, "
+ "ee.responseCompletionTime, ee.responseSizeAverage, ee.requestSizeAverage, ee.responseTime "
+ "ORDER BY ee.domainName, ee.serviceName, ec.message, ee.errorTimestamp");
#SuppressWarnings("unchecked")
List<ErrorsDTOEntity> services = (List<ErrorsDTOEntity>) query.list();
return services;
} catch (HibernateException hex) {
hex.printStackTrace();
}
return null;
}
This is throwing the following SQL error:
org.hibernate.exception.SQLGrammarException: ORA-00932: inconsistent datatypes: expected TIMESTAMP got NUMBER
What's the proper way to structure this query so I can only fetch results between the from and to dates?
I figured it out, this works:
#Override
public List<ErrorsDTOEntity> getAllErrors(Date from, Date to) {
try {
Query query = getSession().createQuery(
"SELECT NEW com.mydomain.esb.jpa.dto.ErrorsDTOEntity(ee, ec.message) "
+ "FROM ErrorsEntity ee, EventCodeEntity ec "
+ "WHERE ee.responseTime > :from "
+ "AND ee.responseTime < :to "
+ "AND ee.serviceResponseCode = ec.code "
+ "GROUP BY ee.domainName, ee.serviceName, ec.message, ee.serviceErrorCount, ee.errorTimestamp, "
+ "ee.deviceName, ee.servErrId, ee.serviceResponseCode, ee.elapsedTime, ee.forwardTime, "
+ "ee.responseCompletionTime, ee.responseSizeAverage, ee.requestSizeAverage, ee.responseTime "
+ "ORDER BY ee.domainName, ee.serviceName, ec.message, ee.errorTimestamp");
query.setTimestamp("from", from);
query.setTimestamp("to", to);
#SuppressWarnings("unchecked")
List<ErrorsDTOEntity> services = (List<ErrorsDTOEntity>) query.list();
return services;
} catch (HibernateException hex) {
hex.printStackTrace();
}
return null;
}

hibernate subselect return null

I'm using subselect in hibernate to return an object that contains id on all related table instead of object.
this the dto that I defined
#Entity
#Subselect("select di.id as id, user.id as userId, client.id as clientId, controller.id as controllerId,"
+ "supplier.id as supplierId, grade.id as gradeId, packing.id as packingId, warehouse.id as warehouseId,"
+ "qualityController.id as qualityControllerId,"
+ "companyMasterByPledger.id as pledgerId,"
+ "di.refNumber as refNumber,"
+ "di.clientRef as clientRef,"
+ "di.date as date,"
+ "di.supplierRef as supplierRef,"
+ "di.tons as tons,"
+ "di.kgPerBag as kgPerBag,"
+ "di.noOfBags as noOfBags,"
+ "di.deliveryDate as deliveryDate,"
+ "di.fromTime as fromTime,"
+ "di.toTime as toTime,"
+ "di.markingOnBags as markingOnBags,"
+ "di.originId as originId,"
+ "di.qualityId as qualityId,"
+ "di.remarks as remarks,"
+ "di.status as status,"
+ "di.log as log "
+ "from DeliveryInstruction as di "
+ "left join di.user as user "
+ "left join di.companyMasterByClientId as client "
+ "left join di.companyMasterByWeightControllerId as controller "
+ "left join di.companyMasterBySupplierId as supplier "
+ "left join di.gradeMaster as grade "
+ "left join di.packingMaster as packing "
+ "left join di.companyMasterByQualityControllerId as qualityController "
+ "left join di.companyMasterByPledger as pledger "
+ "left join di.warehouse as warehouse")
#Synchronize({"DeliveryInstruction"})
public class DeliveryView implements Serializable{
private Integer id;
private Integer userId;
private Integer clientId;
private Integer controllerId;
private Integer supplierId;
private Integer gradeId;
private Integer packingId;
private Integer warehouseId;
private Integer qualityControllerId;
private Integer pledgerId;
private String refNumber;
private String clientRef;
private Date date;
private String supplierRef;
private Double tons;
private Float kgPerBag;
private Integer noOfBags;
private Date deliveryDate;
private String fromTime;
private String toTime;
private String markingOnBags;
private Integer originId;
private Integer qualityId;
private String remark;
private Byte status;
private String log;
public DeliveryView() {
}
public DeliveryView(Integer id, Integer userId, Integer clientId, Integer controllerId, Integer supplierId, Integer gradeId, Integer packingId, Integer warehouseId, Integer qualityControllerId, Integer pledgerId, String refNumber, String clientRef, Date date, String supplierRef, Double tons, Float kgPerBag, Integer noOfBags, Date deliveryDate, String fromTime, String toTime, String markingOnBags, Integer originId, Integer qualityId, String remark, Byte status, String log) {
this.id = id;
this.userId = userId;
this.clientId = clientId;
this.controllerId = controllerId;
this.supplierId = supplierId;
this.gradeId = gradeId;
this.packingId = packingId;
this.warehouseId = warehouseId;
this.qualityControllerId = qualityControllerId;
this.pledgerId = pledgerId;
this.refNumber = refNumber;
this.clientRef = clientRef;
this.date = date;
this.supplierRef = supplierRef;
this.tons = tons;
this.kgPerBag = kgPerBag;
this.noOfBags = noOfBags;
this.deliveryDate = deliveryDate;
this.fromTime = fromTime;
this.toTime = toTime;
this.markingOnBags = markingOnBags;
this.originId = originId;
this.qualityId = qualityId;
this.remark = remark;
this.status = status;
this.log = log;
}
#Id
public Integer getId() {
return id;
}
// ... others getter and setter
}
and in the DAO class, the method looks like below
public DeliveryView getDiById(int id) {
return (DeliveryView) getHibernateTemplate().get(DeliveryView.class, id);
}
However when I use the above method, it returned null.
When I run the method, the script that is printed to the console is
select deliveryvi0_.id as id36_0_, deliveryvi0_.clientId as clientId36_0_, deliveryvi0_.clientRef as clientRef36_0_, deliveryvi0_.controllerId as controll4_36_0_, deliveryvi0_.date as date36_0_, deliveryvi0_.deliveryDate as delivery6_36_0_, deliveryvi0_.fromTime as fromTime36_0_, deliveryvi0_.gradeId as gradeId36_0_, deliveryvi0_.kgPerBag as kgPerBag36_0_, deliveryvi0_.log as log36_0_, deliveryvi0_.markingOnBags as marking11_36_0_, deliveryvi0_.noOfBags as noOfBags36_0_, deliveryvi0_.originId as originId36_0_, deliveryvi0_.packingId as packingId36_0_, deliveryvi0_.pledgerId as pledgerId36_0_, deliveryvi0_.qualityControllerId as quality16_36_0_, deliveryvi0_.qualityId as qualityId36_0_, deliveryvi0_.refNumber as refNumber36_0_, deliveryvi0_.remark as remark36_0_, deliveryvi0_.status as status36_0_, deliveryvi0_.supplierId as supplierId36_0_, deliveryvi0_.supplierRef as supplie22_36_0_, deliveryvi0_.toTime as toTime36_0_, deliveryvi0_.tons as tons36_0_, deliveryvi0_.userId as userId36_0_, deliveryvi0_.warehouseId as warehou26_36_0_ from DeliveryView deliveryvi0_ where deliveryvi0_.id=?
it gets the data from DeliveryView table which does not exist, what I want is to get the data from DeliveryInstruction table. Please help me to correct it, thanks
P/s: I'm using spring and hibernate and I do this way to work with jackson to prevent it load a lot of redundant information (I used jackson hibernate module, but it returned a lot of unneccessary information, instead of only id). So if you have any better idea, please tell me, thanks.
Update: I saw that the script on #subselect didn't run, it execute the default script "select * from deliveryView" when I call "get(DeliveryView.class, id)" method.
Update: This my native script that I've checked
select di.id as id, user.id as userId, client.id as clientId, controller.id as controllerId,
supplier.id as supplierId, grade.id as gradeId, packing.id as packingId, warehouse.id as warehouseId,
qualityController.id as qualityControllerId,
pledger.id as pledgerId,
di.ref_number as refNumber,
di.client_ref as clientRef,
di.date as date,
di.supplier_ref as supplierRef,
di.tons as tons,
di.kg_per_bag as kgPerBag,
di.no_of_bags as noOfBags,
di.delivery_date as deliveryDate,
di.from_time as fromTime,
di.to_time as toTime,
di.marking_on_bags as markingOnBags,
di.origin_id as originId,
di.quality_id as qualityId,
di.remark as remarks,
di.status as status,
di.log as log
from delivery_instruction di
left join user on user.id = di.user_id
left join company_master client on client.id = di.client_id
left join company_master controller on controller.id = di.weight_controller_id
left join company_master supplier on supplier.id = di.supplier_id
left join grade_master grade on grade.id = di.grade_id
left join packing_master packing on packing.id = di.packing_id
left join company_master qualityController on qualityController.id = di.quality_controller_id
left join company_master pledger on pledger.id = di.pledger
left join warehouse on warehouse.id = di.warehouse_id
where di.id = 21
1 Create simple class(without annotations) that holds all properties you need with getters and setters
2 Execute native sql:
public DeliveryView getDiById(int id) {
DeliveryView dV = (DeliveryView) sessionFactory.getCurrentSession()
.createSQLQuery(yourQueryHere).setResultTransformer(
new AliasToBeanResultTransformer(DeliveryView.class)).uniqueResult();
return dV;
}

Resources