I am using Hibernate (and new at it also) and trying to use an aggregate function to retrieve count value and additional fields from a MS SQL database. I have created a POJO class for the data as follows:
package com.hdl.model.db;
import java.util.Date;
#Entity
#Table(name = "sfdc_stg_lab_orders")
#SqlResultSetMappings( {
SqlResultSetMapping(name = "ProfessorAndManager",
columns = { #ColumnResult(name = "total"),
#ColumnResult(name = "org_name"),
#ColumnResult(name = "drawMonth"),
#ColumnResult(name = "drawYear")
})
})
public class OrgnameByMonthYear {
public OrgnameByMonthYear(Id sfdc_stg_lab_order_key, String org_name,int drawMonth,
int drawYear , Double total){
this.org_name = org_name;
this.total = total;
this.drawMonth = drawMonth;
this.drawYear = drawYear;
}
#Id
#GeneratedValue
#Column(name= "sfdc_stg_lab_order_key")
/*
* Unique ID - System Generated
*/
private Integer sfdc_stg_lab_order_key;
/*
* Name of the Organization
*/
#Column(name= "org_name")
private String org_name;
#Column(name = "total")
private double total;
#Column(name = "drawMonth")
private int drawMonth;
#Column(name = "drawYear")
private int drawYear;
public Integer getSfdc_stg_lab_order_key() {
return sfdc_stg_lab_order_key;
}
public void setSfdc_stg_lab_order_key(Integer sfdc_stg_lab_order_key) {
this.sfdc_stg_lab_order_key = sfdc_stg_lab_order_key;
}
/**
* #return the orgname
*/
public String getOrg_name() {
return org_name;
}
/**
* #param orgname to set
*/
public void setOrg_name(String org_name) {
this.org_name = org_name;
}
/**
* #return the year
*/
public double getTotal() {
return total;
}
/**
* #param total to set
*/
public void setTotal(long total) {
this.total = total;
}
/**
* #return the month
*/
public int getDrawMonth() {
return drawMonth;
}
/**
* #param month to set
*/
public void setDrawMonth(int drawMonth) {
this.drawMonth = drawMonth;
}
/**
* #return the year
*/
public int getDrawYear() {
return drawYear;
}
/**
* #param year to set
*/
public void setDrawYear(int drawYear) {
this.drawYear = drawYear;
}
#Override
public String toString() {
return "sfdc_stg_lab_orders [sfdc_stg_lab_order_key=" +
sfdc_stg_lab_order_key + "total=" + total + ", org_name=" + org_name + "]";
}
}
I am calling the following to retrieve the data using Hibernate find:
#SuppressWarnings("unchecked")
#Override
public List<OrgnameByMonthYear> getOrgnameByMonthYear() {
logger.info("Retrieving getOrgnameByMonthYear list inside SfdcStgLabOrdersDAOImpl ....");
return hibernateTemplate.find("select count(org_name) AS total, org_name,
month(specimen_draw_date_1) AS drawMonth, year(specimen_draw_date_1) AS drawYear from
OrgnameByMonthYear group by org_name, month(specimen_draw_date_1),
year(specimen_draw_date_1)");
}
I am getting the following error in Java "Unable to cast to OrgnameByMonthYear class". Thanks in advance for any assistance!
org.springframework.scheduling.quartz.JobMethodInvocationFailedException: Invocation of method 'executeFirstTask' on target class [class com.hdl.service.impl.SchedulerService] failed; nested exception is java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.hdl.model.db.OrgnameByMonthYear at
org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:320) at
org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:113)
at org.quartz.core.JobRunShell.run(JobRunShell.java:223)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)
Caused by: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.hdl.model.db.OrgnameByMonthYear
This can be done by creating a new class AggregationResults that contains the results of the query:
public class AggregationResults {
private Integer total;
private String orgName;
private Integer drawMonth;
private Integer drawYear;
... constructor with all properties here ...
}
And then rewrite the query so that it returns AggregationResults using the new operator:
#SuppressWarnings("unchecked")
#Override
public List<AggregationResults> getOrgnameByMonthYear() {
logger.info("Retrieving AggregationResults list inside SfdcStgLabOrdersDAOImpl ....");
return hibernateTemplate.find("select new com.your.package.AggregationResults( count(org_name) AS total, org_name,
month(specimen_draw_date_1) AS drawMonth, year(specimen_draw_date_1) AS drawYear) from
OrgnameByMonthYear group by org_name, month(specimen_draw_date_1),
year(specimen_draw_date_1)");
}
Related
I have a view with many fields as query filters, and I am using JPA derived queries , however creating all queries for every combination of fields/filters would be tedious and long.
I found out that I can create a dynamic query for it, but not sure how.
So far I have created these queries in my repository, but still need a lot more :
public interface EmployeeReportInfoViewRepository extends PagingAndSortingRepository<EmployeeReportInfo, Long> {
List<EmployeeReportInfo> findByControlNumber(String controlNmber);
List<EmployeeReportInfo> findByManager(String manager);
List<EmployeeReportInfo> findByofficeLocation(String officeLocation);
List<EmployeeReportInfo> findByBenchFlag(char benchFlag);
List<EmployeeReportInfo> findByBillableFlag(char billableFlag);
List<EmployeeReportInfo> findByEnableFlag(boolean enableFlag);
List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumber(String lastName, String firstName,String controlNumber);
List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumberAndManager(String lastName, String firstName,String controlNmber,String manager);
List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumberAndManagerAndOfficeLocation(String lastName, String firstName,String controlNmber,String manager,String officeLocation);
List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumberAndManagerAndOfficeLocationAndBenchFlag(String lastName, String firstName,String controlNmber,String manager,String officeLocation, char benchFlag);
List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumberAndManagerAndOfficeLocationAndBenchFlagAndBillableFlag(String lastName, String firstName,String controlNmber,String manager,String officeLocation, char benchFlag,char bllableFlag);
List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumberAndManagerAndOfficeLocationAndBenchFlagAndBillableFlagAndEnableFlagAndStartGreaterThanEqualAndEndLessThanEqual
(String lastName, String firstName,String controlNmber,String manager,String officeLocation, char benchFlag,char bllableFlag,
boolean emableFlag, Date start,Date end);
}
#Entity
#Table(name = "employee_report_view")
public class EmployeeReportInfo {
#Id
#Column(name = "employee_id")
private Long id;
private String name;
private Date start;
private Date end;
#Column(name = "control_number")
private String controlNumber;
#Column(name = "enable_flag")
private boolean enableFlag;
#Column(name = "billable_flag")
private char billableFlag;
#Column(name = "bench_flag")
private char benchFlag;
#Column(name = "office_location")
private String officeLocation;
#Column(name = "manager")
private String manager;
/**
* #return the id
*/
public Long getId() {
return id;
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* #param id the id to set
*/
public void setId(Long id) {
this.id = id;
}
/**
* #return the start
*/
public Date getStart() {
return start;
}
/**
* #param start the start to set
*/
public void setStart(Date start) {
this.start = start;
}
/**
* #return the end
*/
public Date getEnd() {
return end;
}
/**
* #param end the end to set
*/
public void setEnd(Date end) {
this.end = end;
}
/**
* #return the controlNumber
*/
public String getControlNumber() {
return controlNumber;
}
/**
* #param controlNumber the controlNumber to set
*/
public void setControlNumber(String controlNumber) {
this.controlNumber = controlNumber;
}
/**
* #return the enableFlag
*/
public boolean isEnableFlag() {
return enableFlag;
}
/**
* #param enableFlag the enableFlag to set
*/
public void setEnableFlag(boolean enableFlag) {
this.enableFlag = enableFlag;
}
/**
* #return the billableFlag
*/
public char getBillableFlag() {
return billableFlag;
}
/**
* #param billableFlag the billableFlag to set
*/
public void setBillableFlag(char billableFlag) {
this.billableFlag = billableFlag;
}
/**
* #return the benchFlag
*/
public char getBenchFlag() {
return benchFlag;
}
/**
* #param benchFlag the benchFlag to set
*/
public void setBenchFlag(char benchFlag) {
this.benchFlag = benchFlag;
}
/**
* #return the officeLocation
*/
public String getOfficeLocation() {
return officeLocation;
}
/**
* #param officeLocation the officeLocation to set
*/
public void setOfficeLocation(String officeLocation) {
this.officeLocation = officeLocation;
}
/**
* #return the manager
*/
public String getManager() {
return manager;
}
/**
* #param manager the manager to set
*/
public void setManager(String manager) {
this.manager = manager;
}
}
I can understand your needs:you want to dynamically generate query conditions based on the url issued by the form.Let's assume that the url maps to the back end to a HashMap<String,String>.
For instance,url:
127.0.0.1/employees?nameContains=jack&ageEquals=10
Map:
HashMap<String, String>:key:nameContains,value:jack,key:ageEuqals,value:10
The Spring framework can do this mapping automatically(RequestParamMapMethodArgumentResolver). What you need to do is to dynamically generate the Specification(Specification) by this map.
Gets the type of property corresponding to the field using reflect : name=>String, age=>Integer
Using CriteriaBuilder to build query criteria,it has comprehensive api,such as:
Predicate like(Expression x, String pattern); => contains
Predicate equal(Expression x, Expression y); => equal
Assemble your query criteria(or,and)
You get a Specification.
This is a relatively complex solution idea, which requires the coordination between the front table component and the back end, but it will be very convenient.
What I said is relatively simple and general, there are a lot of details.(such as nested properties,one-to-one,one-to-many,etc)
Also,You can have a look http://www.querydsl.com/
I'm currently trying to deserialize a json-response. My object uses the builder pattern and the consumer interface.
I'm doing a http-request to an external source and get my response as json. All the responses are strings and look like:
{
"a": "198",
"b": "F",
"c": "30",
"d": "2019-02-01",
"e": "2019-12-31"
}
I've changed the name of my model and my key to Model and Key so there might be typos, sorry for that.
#JsonDeserialize(builder = Model.Builder.class)
public class Model {
private final Data data;
private Model() {
this.data = new Data();
}
/**
* #return key
*/
public Key getKey() {
return data.key;
}
/**
* #return Tax Form
*/
public String getTaxForm() {
return data.taxForm;
}
/**
* #return tax table
*/
public int getTaxTable() {
return data.taxTable;
}
/**
* #return tax percent
*/
public BigDecimal getTaxPercent() {
return data.taxPercent;
}
/**
* #return Valid from
*/
public LocalDate getValidFrom() {
return data.validFrom;
}
/**
* #return Valid to
*/
public LocalDate getValidTo() {
return data.validTo;
}
/**
* #param key key
* #return builder
*/
public static Builder getBuilder(Key key) {
return new Builder(key);
}
/**
* #param model the response
* #return builder
*/
public static Builder getBuilder(Model model) {
return new Builder(model);
}
/**
* builder
*/
public static class Builder {
#JsonDeserialize(as = Model.Data.class)
private final Data data;
#JsonCreator
private Builder(Key key) {
this.data = new Data();
this.data.key = key;
}
private Builder(Model model) {
this(model.data.key);
data.taxForm = model.data.taxForm;
data.taxTable = model.data.taxTable;
data.taxPercent = model.data.taxPercent;
data.validFrom = model.data.validFrom;
data.validTo = model.data.validTo;
}
public Builder with(Consumer<Data> consumer) {
consumer.accept(this.data);
return this;
}
public Model build() {
Model internalModel = new Model();
internalModel.data.key = data.key;
internalModel.data.taxForm = data.taxForm;
internalModel.data.taxTable = data.taxTable;
internalModel.data.taxPercent = data.taxPercent;
internalModel.data.validFrom = data.validFrom;
internalModel.data.validTo = data.validTo;
return internalModel;
}
}
/**
* Data
*/
public static final class Data implements Serializable {
private Key key;
#JsonProperty("b")
public String taxForm;
public int taxTable;
public BigDecimal taxPercent;
public LocalDate validFrom;
public LocalDate validTo;
}
}
public class Key {
private final String personalNumber;
public Key(#JsonProperty("a") String personalNumber) {
this.personalNumber = personalNumber;
}
public String getPersonalNumber() {
return personalNumber;
}
}
Currently I am able to deserialize a, but all the other fields are missed. I tried using #JsonProperty in the Data class but that doesn't work. Any ideas?
I am creating a REST API from java where I am returning an object list as follows:
#Path("/order")
public class OrderService implements IService
{
#Override
public Response get()
{
List<DataObj> list = new ArrayList<>();
List<SubDataObj> subList = new ArrayList<>();
subList.add(new SubDataObj("1"));
GenericEntity<List<DataObj>> entity;
list.add(new DataObj("A", "22", TestEnum.test1, DateTime.now(), subList));
list.add(new DataObj("B", "23", TestEnum.test2, DateTime.now(), subList));
entity = new GenericEntity<List<DataObj>>(list){};
return Response.ok(entity).build();
}
}
Here the service returns the Response fine when not using the subList, which is a object list within the DataObj class. However, when I am using it, i get an error as:
SEVERE: MessageBodyWriter not found for media type=application/json, type=class java.util.ArrayList, genericType=java.util.List<dyno.scheduler.restservice.DataObj>.
Here are the DataObj and the SubDataObj classes:
#XmlRootElement
class DataObj
{
private String name;
private String age;
private TestEnum enumVal;
private DateTime currentDate;
private List<SubDataObj> subData;
public DataObj(String name, String age, TestEnum enumVal, DateTime currentDate, List<SubDataObj> subData)
{
this.name = name;
this.age = age;
this.enumVal = enumVal;
this.currentDate = currentDate;
this.subData = subData;
}
public DataObj() {}
/**
* #return the name
*/
public String getName()
{
return name;
}
/**
* #param name the name to set
*/
public void setName(String name)
{
this.name = name;
}
/**
* #return the age
*/
public String getAge()
{
return age;
}
/**
* #param age the age to set
*/
public void setAge(String age)
{
this.age = age;
}
/**
* #return the enumVal
*/
public TestEnum getEnumVal()
{
return enumVal;
}
/**
* #param enumVal the enumVal to set
*/
public void setEnumVal(TestEnum enumVal)
{
this.enumVal = enumVal;
}
/**
* #return the currentDate
*/
public DateTime getCurrentDate()
{
return currentDate;
}
/**
* #param currentDate the currentDate to set
*/
public void setCurrentDate(DateTime currentDate)
{
this.currentDate = currentDate;
}
/**
* #return the subData
*/
public List<SubDataObj> getSubData()
{
return subData;
}
/**
* #param subData the subData to set
*/
public void setSubData(List<SubDataObj> subData)
{
this.subData = subData;
}
}
DataSubObj class:
class SubDataObj
{
private String subId;
public SubDataObj(String subId)
{
this.subId = subId;
}
/**
* #return the subId
*/
public String getSubId()
{
return subId;
}
/**
* #param subId the subId to set
*/
public void setSubId(String subId)
{
this.subId = subId;
}
}
I tried adding #XmlRootElement annotation to my SubDataObj class as well, which didn't work.
Any help would be appreciated!
I have 25+ tables and I have used Content Provider with Database.
I have created separate files for each tables with following structure:
TProductUnit.java in package of com.myapp.db.tables
public class TProductUnit {
/***
* Fields of TABLE_PRODUCT_UNIT Table
***/
public static final String TABLE_PRODUCT_UNIT = "product_unit";
/**
* Columns of TABLE_PRODUCT_UNIT
*/
public static final String PRODUCT_UNIT_SERVER_ID = "id";
public static final String PRODUCT_UNIT_NAME = "name";
public static final String PRODUCT_UNIT_ITP = "itp";
public static final String PRODUCT_UNIT_UTP = "utp";
public static final String PRODUCT_UNIT_STATUS = "status";
public static String[] PRODUCT_UNIT_COLUMNS = new String[] {
BaseColumns._ID,
PRODUCT_UNIT_SERVER_ID,
PRODUCT_UNIT_NAME,
PRODUCT_UNIT_ITP,
PRODUCT_UNIT_UTP,
PRODUCT_UNIT_STATUS
};
}
ProductUnit.java is POJO class which will helpful when First time get data from Server.
public class ProductUnit {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("product_id")
#Expose
private Integer productId;
#SerializedName("url")
#Expose
private String url;
#SerializedName("bit")
#Expose
private int bit;
#SerializedName("status")
#Expose
private Integer status;
#SerializedName("itp")
#Expose
private String itp;
#SerializedName("utp")
#Expose
private String utp;
/**
* #return The id
*/
public Integer getId() {
return id;
}
/**
* #param id The id
*/
public void setId(Integer id) {
this.id = id;
}
public Integer getProductId() {
return productId;
}
public void setProductId(Integer productId) {
this.productId = productId;
}
public int getBit() {
return bit;
}
public void setBit(int bit) {
this.bit = bit;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
/**
* #return The status
*/
public Integer getStatus() {
return status;
}
/**
* #param status The status
*/
public void setStatus(Integer status) {
this.status = status;
}
/**
* #return The itp
*/
public String getItp() {
return itp;
}
/**
* #param itp The itp
*/
public void setItp(String itp) {
this.itp = itp;
}
/**
* #return The utp
*/
public String getUtp() {
return utp;
}
/**
* #param utp The utp
*/
public void setUtp(String utp) {
this.utp = utp;
}
/**
* Convenient method to get the objects data members in ContentValues object.
* This will be useful for Content Provider operations,
* which use ContentValues object to represent the data.
*
* #return
*/
public ContentValues getContentValues() {
ContentValues values = new ContentValues();
values.put(PRODUCT_UNIT_SERVER_ID, id);
values.put(PRODUCT_UNIT_NAME, name);
values.put(PRODUCT_UNIT_ITP, itp);
values.put(PRODUCT_UNIT_UTP, utp);
values.put(PRODUCT_UNIT_STATUS, status);
return values;
}
}
Both classes have most of the same number of fields with same values if we think about #SerializedName
Problem:
Whenever I need to add some fields in any Particular Table then I have to add in all Table file and JSON POJO Class too.
When any field name changed by server side then I have to change in both file.
My Question is: Is there any better solution for this optimization. Have you ever manage like this?
P.S. I have 25+ tables so I have to create 50+ classes.
Help please. Thanks.
hi guys I have created a basket field in this browser class but, however I now need to declare this basket field in the browser class as arraylist collection class object but cant figure out how to do this, below is my code so far
/**
* Write a description of class Browser here.
*
* #author (johnson)
* #version (10/12/13)
*/
public class Browser
{
// instance variables - replace the example below with your own
private int iD;
private String email;
private int yearOfBirth;
private boolean memberID;
private WineCase wineCase;
private boolean loggedIn;
private Website website;
private boolean discount;
List<Boolean> basketList = new ArrayList<Boolean>();
/**
* Constructor for objects of class Browser
*/
public Browser()
{
// initialise instance variables
wineCase = null;
website = null;
iD = 00065;
yearOfBirth = 1992;
memberID = true;
discount = false;
}
/**
* Constructor for objects of class Browser
*/
public Browser(String newEmail,int newYearOfBirth)
{
// initialise instance variables
wineCase = null;
website = null;
iD = 0;
email = newEmail;
yearOfBirth = newYearOfBirth;
loggedIn = false;
memberID = true;
discount = false;
}
/**
* Constructor for objects of class Browser
*/
public Browser(int newID, String newEmail,int newYearOfBirth)
{
// initialise instance variables
wineCase = null;
website = null;
iD = newID;
email = newEmail;
yearOfBirth = newYearOfBirth;
memberID = true;
discount = false;
}
/**
* returns the ID
*/
public int getId()
{
return iD;
}
/**
* gets the email of the browser class
*/
public String getEmail()
{
return email;
}
public boolean getDiscount()
{
return discount;
}
/**
* gets the yearOfBirth for the browser class
*/
public int yearOfBirth()
{
return yearOfBirth;
}
public double getWineCost()
{
return wineCase.getWineCost();
}
/**
* returns
*/
public void setLoginStatus(boolean status)
{
loggedIn = status;
}
/**
* returns
*/
public void selectWineCase(WineCase winecase)
{
wineCase = winecase;
System.out.println ("Browser "+getId()+" has selcted wine case"+wineCase.getRefNo()+ "of "+winecase.getNoOfBottles()+ wineCase.getDescription()+ " at £"+wineCase.getWineCost());
}
/**
* returns
*/
public void payForWine()
{
website.checkout(this);
}
public void setId()
{
iD = 999;
}
public void setWebSite(Website website)
{
this.website = website;
}
public void setDiscount(boolean discount)
{
this.discount = discount;
}
}
any answers or replies would be greatly appreciated
Try this out
List<Boolean> basketList = new ArrayList<Boolean>();
That must not be boolean as boolean is a primitive type not a collection of Objects.
what you need to do is:
ArrayList basket = new ArrayList();
Or if you need a collection of Boolean Objects (still not boolean) you can do:
ArrayList basket = new ArrayList();
A list of Boolean(s)?
java.util.List<Boolean> basketAl = new java.util.ArrayList<Boolean>();
And I urge you to add a toString method to your class
// Something like this...
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(iD).append(" ").append(email).append(" ");
sb.append(yearOfBirth).append(" ").append(memberID).append(" ");
sb.append(wineCase).append(" ").append(loggedIn).append(" ");
sb.append(website).append(" ").append(discount).append(" ");
sb.append(Basket);
return sb.toString();
}
It's a bit hard to tell what you're doing but declare this at the top of your class. Also, don't forget to import packages java.util.ArrayList and import java.util.List.
private List<Boolean> baskets = new ArrayList<Boolean>();
This will replace the previous declaration of:
private boolean Basket;