I am experiencing strange behavior. I am using hibernate. I have two tables.
#Entity
public class Nemocnica implements java.io.Serializable {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="N_ID")
private BigDecimal NId;
#Column(name="adresa")
private String adresa;
#OneToMany
private Set sanitkas = new HashSet(0);
public Nemocnica() {
}
public Nemocnica( String adresa) {
this.NId = NId;
}
public Nemocnica(BigDecimal NId, String adresa) {
this.NId = NId;
this.adresa = adresa;
}
public Nemocnica(BigDecimal NId, String adresa, Set sanitkas) {
this.NId = NId;
this.adresa = adresa;
this.sanitkas = sanitkas;
}
public BigDecimal getNId() {
return this.NId;
}
public void setNId(BigDecimal NId) {
this.NId = NId;
}
public String getAdresa() {
return this.adresa;
}
public void setAdresa(String adresa) {
this.adresa = adresa;
}
public Set getSanitkas() {
return this.sanitkas;
}
public void setSanitkas(Set sanitkas) {
this.sanitkas = sanitkas;
}
}
and second
#Entity
public class Sanitka implements java.io.Serializable {
private BigDecimal sanitkaId;
private transient Nemocnica nemocnica;
private BigDecimal kapacita;
#ManyToOne
#JoinColumn(name="nemocnica_n_id")
private Set sanitaris = new HashSet(0);
public Sanitka() {
}
public Sanitka(BigDecimal sanitkaId, Nemocnica nemocnica, BigDecimal kapacita) {
this.sanitkaId = sanitkaId;
this.nemocnica = nemocnica;
this.kapacita = kapacita;
}
public Sanitka(BigDecimal sanitkaId, Nemocnica nemocnica, BigDecimal kapacita, Set sanitaris) {
this.sanitkaId = sanitkaId;
this.nemocnica = nemocnica;
this.kapacita = kapacita;
this.sanitaris = sanitaris;
}
public BigDecimal getSanitkaId() {
return this.sanitkaId;
}
public void setSanitkaId(BigDecimal sanitkaId) {
this.sanitkaId = sanitkaId;
}
#ManyToOne(cascade=CascadeType.ALL)
public Nemocnica getNemocnica() {
return this.nemocnica;
}
public void setNemocnica(Nemocnica nemocnica) {
this.nemocnica = nemocnica;
}
public BigDecimal getKapacita() {
return this.kapacita;
}
public void setKapacita(BigDecimal kapacita) {
this.kapacita = kapacita;
}
public Set getSanitaris() {
return this.sanitaris;
}
public void setSanitaris(Set sanitaris) {
this.sanitaris = sanitaris;
}
}
And routes that mannipulate with them.
nemocnicaRoute:
#Path("nemocnica")
public class nemocnicaRoute {
// private static final helper db = new helper();
#GET
#Path("all")
#Produces(MediaType.APPLICATION_JSON)
public String getName(){
List<Nemocnica> l = db.helper.getNemocnicas();
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
//System.out.println( json );
//return l.toString();
return gson.toJson(l);
}
// another methods
}
sanitkaRoute
#Path("sanitka")
public class sanitkaRoute {
//private static final helper db = new helper();
#GET
#Path("all")
#Produces("text/plain")
public String getName(){
List<Sanitka> l = db.helper.getSanitkas();
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
//System.out.println( json );
//return l.toString();
return gson.toJson(l);
}
// another methods
}
I am using these two getName() methods to retrieve all data from said tables.
This cause strange behavior , if i invoke get request on nemocnicaRoute first , it works very well as it should.
However when i invoke get requet on sanitkaRoute first , it works but after that when i want to invoke get request on nemocniceRoute it throws
java.lang.UnsupportedOperationException: Attempted to serialize
java.lang.Class: org.hibernate.proxy.HibernateProxy. Forgot to
register a type adapter?
Which confuses me , bcs this does not happen when i invoke getRequest on nemocnicaRoute first.
How could i fix this strange behavior?
All help appreciated
Related
I am doing a liferay project which use ejb at back end. so my ejb method looks like this:-
#Override
public List<RmisPaymentDetailsDto> getEpaymentDetails(String ebpCode) {
Query q = entityManager.createQuery("select s from EpaymentBo s where s.ebpCode=:ebpcode")
.setParameter("ebpcode",ebpCode);
#SuppressWarnings("unchecked")
List<ProductBo> list = q.getResultList();
Iterator<ProductBo> i = list.iterator();
List<RmisPaymentDetailsDto> rList = new ArrayList<RmisPaymentDetailsDto>();
while(i.hasNext()){
EpaymentBo ep =(EpaymentBo) i.next();
RmisPaymentDetailsDto dto = new RmisPaymentDetailsDto();
dto.setAdvertisementcode(ep.getAdvertisementcode());
dto.setAmount(ep.getAmount());
dto.setStudentmasterid(ep.getStudentmasterid());
dto.setEbpgendate(ep.getEbp_gen_date());
dto.setEbpcode(ep.getEbpCode());
dto.setPaymentstatus(ep.getPaymentstatus());
dto.setCandidatenameinnepali(ep.getCandidatenameinnepali());
rList.add(dto);
}
return rList;
}
the above method successfully fetches data from database and sets it to my RmisPaymentDetailsDto.
like this:-
now i am calling same method from my liferay controlller.
PreExaminationRemote preRef = (PreExaminationRemote) jndiContext
.lookup("PreExamination/remote");
List<RmisPaymentDetailsDto> rDto = preRef.getEpaymentDetails(ebpCode);
I am wondering how my one property(candidatenameinnepali) is lost as i return same dto from my ejb.
My dto looks like this:-
public class RmisPaymentDetailsDto implements Serializable {
private static final long serialVersionUID = 1L;
private String advertisementcode;
private String ebpcode;
private String amount;
private String studentmasterid;
private Date ebpgendate;
private String paymentstatus;
private String candidatenameinnepali;
public String getCandidatenameinnepali() {
return candidatenameinnepali;
}
public void setCandidatenameinnepali(String candidatenameinnepali) {
this.candidatenameinnepali = candidatenameinnepali;
}
public String getAdvertisementcode() {
return advertisementcode;
}
public void setAdvertisementcode(String advertisementcode) {
this.advertisementcode = advertisementcode;
}
public String getEbpcode() {
return ebpcode;
}
public void setEbpcode(String ebpcode) {
this.ebpcode = ebpcode;
}
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
public String getStudentmasterid() {
return studentmasterid;
}
public void setStudentmasterid(String studentmasterid) {
this.studentmasterid = studentmasterid;
}
public Date getEbpgendate() {
return ebpgendate;
}
public void setEbpgendate(Date ebpgendate) {
this.ebpgendate = ebpgendate;
}
public String getPaymentstatus() {
return paymentstatus;
}
public void setPaymentstatus(String paymentstatus) {
this.paymentstatus = paymentstatus;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
}
in this case, i want to show Json to an response page in java hibernate, query method from DAO like this:
public List<TransactionQR> getAllTransaction() throws HibernateException {
return this.session.createQuery("FROM TransactionQR tr, Batch b, Terminal t, User_Smartphone us, Merchant mc WHERE tr.batch = b.id AND b.user_smartphone = us.id AND b.terminal = t.id AND t.merchant = mc.id AND state = '1' ").list();
}
then in servlet class i try to convert the list into json using Json object and json array then write in response like this:
int start = 0;
String jsonResult = null;
JSONObject jo=new JSONObject();
HttpServletRequest request = context.getRequest();
HttpServletResponse response = context.getResponse();
HttpSession session = context.getSession();
DB db = getDB(context);
//JSONObject jo = new JSONObject();
QRTransactionDao QR = new QRTransactionDao(db);
//Gson objGson = new GsonBuilder().setPrettyPrinting().create();
//String json = objGson.toJson(QR.getAllTransaction());
//System.out.println(json);
List<TransactionQR> str = QR.getAllTransaction();
JSONArray array = new JSONArray();
for(TransactionQR tr : str){
JSONObject str3 = new JSONObject();
str3.put("amount", tr.getAmount());
context.put("jsoncontent", jsonResult);
array.add(str3);
}
jo.put("status", "ok");
jo.put("dataqr", array);
jsonResult=jo.toString();
response.setContentType("application/json");
response.getWriter().print(jsonResult);
but i got the error on syntax in this line loop:
for(TransactionQR tr : str){
the error like this:
[Ljava.lang.Object; cannot be cast to Transaction
here the model Transaction:
package id.co.keriss.consolidate.ee;
import java.io.Serializable;
import java.util.Date;
public class TransactionQR implements Serializable{
private Long id;
private String codeqr;
private Date approvaltime;
private String merchant;
private String code_merchant;
private Long amount;
private Long saldoawal;
private Integer tracenumber;
private String state;
private Date createdate;
private Batch batch;
public TransactionQR() {
}
public TransactionQR(Long id, String codeqr, Date approvaltime, String merchant, String code_merchant, Long amount,
Long saldoawal, Integer tracenumber, String state, Date createdate, Batch batch) {
super();
this.id = id;
this.codeqr = codeqr;
this.approvaltime = approvaltime;
this.merchant = merchant;
this.code_merchant = code_merchant;
this.amount = amount;
this.saldoawal = saldoawal;
this.tracenumber = tracenumber;
this.state = state;
this.createdate = createdate;
this.batch = batch;
}
public Long getId() {
return id;
}
public Date getApprovalTime() {
return approvaltime;
}
public Batch getBatch() {
return batch;
}
public void setBatch(Batch batch) {
this.batch = batch;
}
public void setApprovalTime(Date approvalTime) {
this.approvaltime = approvalTime;
}
public void setId(Long id) {
this.id = id;
}
public Date getApprovaltime() {
return approvaltime;
}
public void setApprovaltime(Date approvaltime) {
this.approvaltime = approvaltime;
}
public String getCodeqr() {
return codeqr;
}
public void setCodeqr(String codeqr) {
this.codeqr = codeqr;
}
public String getMerchant() {
return merchant;
}
public void setMerchant(String merchant) {
this.merchant = merchant;
}
public String getCode_merchant() {
return code_merchant;
}
public void setCode_merchant(String code_merchant) {
this.code_merchant = code_merchant;
}
public Long getAmount() {
return amount;
}
public void setAmount(Long amount) {
this.amount = amount;
}
public Long getSaldoawal() {
return saldoawal;
}
public void setSaldoawal(Long saldoawal) {
this.saldoawal = saldoawal;
}
public Integer getTracenumber() {
return tracenumber;
}
public void setTracenumber(Integer tracenumber) {
this.tracenumber = tracenumber;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Date getCreatedate() {
return createdate;
}
public void setCreatedate(Date createdate) {
this.createdate = createdate;
}
}
i have try to handle the list with Gson:
Gson objGson = new GsonBuilder().setPrettyPrinting().create();
String json = objGson.toJson(QR.getAllTransaction());
System.out.println(json);
in that way, it's work to show but it's not from POJO right i want work with pojo to parse the data to json ?
why i get the error can't cast to model ? any clue ?
Try adding Select tr to your query in getAllTransaction()
Wich is the relation between QRTransactionDao and TransactionQR ?
Mapping an enum class in to DynamoDB object is really simple by using Custom Marshall. But how to map a List of Enum?
Enum class
public enum Transport {
SMS,EMAIL,ALL;
}
DynamoDB mapper
public class Campaign{
private List<Transport> transport;
#DynamoDBAttribute(attributeName = "transport")
public List<Transport> getTransport() {
return transport;
}
public void setTransport(List<Transport> transport) {
this.transport = transport;
}
}
DynamoDBMarshaller is deprecated.
Use DynamoDBTypeConverter instead.
Example:
Enum class
public static enum ValidationFailure {
FRAUD, GENERAL_ERROR
}
DynamoDBTable class
#DynamoDBTable(tableName = "receipt")
public class Receipt {
private Long id;
private List<ValidationFailure> validation;
#DynamoDBHashKey(attributeName = "id")
public Long getId() {
return id;
}
#DynamoDBTypeConverted(converter = ValidationConverter.class)
public List<ValidationFailure> getValidation() {
return validation;
}
public void setId(Long id) {
this.id = id;
}
public void setValidation(List<ValidationFailure> validation) {
this.validation = validation;
}
}
Convertor:
public class ValidationConverter implements DynamoDBTypeConverter<List<String>, List<ValidationFailure>> {
#Override
public List<String> convert(List<ValidationFailure> object) {
List<String> result = new ArrayList<String>();
if (object != null) {
object.stream().forEach(e -> result.add(e.name()));
}
return result;
}
#Override
public List<ValidationFailure> unconvert(List<String> object) {
List<ValidationFailure> result = new ArrayList<ValidationFailure>();
if (object != null) {
object.stream().forEach(e -> result.add(ValidationFailure.valueOf(e)));
}
return result;
}
}
It's working for me, I have used the Set
#DynamoDBTyped(DynamoDBMapperFieldModel.DynamoDBAttributeType.SS)
var roles: MutableSet<Employee.Role>? = null
I think the same approach would work for List with DynamoDBAttributeType.L
I found the answer myself. I create a custom marshall like below.
public class TransportMarshaller implements DynamoDBMarshaller<List<Transport>> {
#Override
public String marshall(List<Transport> transports) {
List<String>transportMap=new ArrayList<>();
for(Transport transport:transports){
transportMap.add(transport.name());
}
return transportMap.toString().replaceAll("\\[|\\]", "");//Save as comma separate value for the purpose of easiness to unmarshall
}
#Override
public List<Transport> unmarshall(Class<List<Transport>> aClass, String s) {
List<String>map= Arrays.asList(s.split("\\s*,\\s*")); //split from comma and parse to List
List<Transport>transports=new ArrayList<>();
for (String st:map){
transports.add(Transport.valueOf(st));
}
return transports;
}
}
I used Gson before and everything worked fine, but it is too slow.
Here is the Json:
"{"Info":[{"par1":3456,"par2":4500,"par3":0,"items":{"parx":2354,"pary":456456,"parz":"worker"}}
,{"par1":34456,"par2":4300,"par3":1,"items":{"parx":5677,"pary":78456,"parz":"member"}},
],"par4":343434,"duplicateItemIdList":null,"errorState":null}"
Now I tried Jackson:
code snippets:
ObjectMapper mapper = new ObjectMapper();
Passes mj = mapper.readValue(str, Passes.class);
public class Passes {
public ArrayList<Info> info;
.... }
#JsonIgnoreProperties(ignoreUnknown = true)
class Info {
public String par1 = "";
public String par2 = "";
public String par3 = "";
public String par4 = "";
Items items = new Items();
}
class Items{
public String parx = "";
public String pary = "";
public String parz = "";
}
the Problem is it doesn't fill the class items. parx,pary,parz etc
items is the only problem. the rest works fine.
my structure has to be right because in Gson I only need two lines and it works perfectly.
so I think I have to add something so that jackson recognizes
Be sure that you have:
geters/setters for each parameter
empty (or any ) Contractor
Passes
#JsonIgnoreProperties(ignoreUnknown = true)
public class Passes {
private List<Info> info;
public Passes() {
// TODO Auto-generated constructor stub
}
public List<Info> getInfo() {
return info;
}
public void setInfo(List<Info> info) {
this.info = info;
}
}
Info
#JsonIgnoreProperties(ignoreUnknown = true)
public class Info {
private int par1;
private int par2;
private int par3;
private int par4;
//private Items items;
public Info() {
// TODO Auto-generated constructor stub
}
public int getPar1() {
return par1;
}
public void setPar1(int par1) {
this.par1 = par1;
}
public int getPar2() {
return par2;
}
public void setPar2(int par2) {
this.par2 = par2;
}
public int getPar3() {
return par3;
}
public void setPar3(int par3) {
this.par3 = par3;
}
public int getPar4() {
return par4;
}
public void setPar4(int par4) {
this.par4 = par4;
}
}
Items
public class Items{
private int parx;
private int pary;
private String parz;
public Items() {
// TODO Auto-generated constructor stub
}
public int getParx() {
return parx;
}
public void setParx(int parx) {
this.parx = parx;
}
public int getPary() {
return pary;
}
public void setPary(int pary) {
this.pary = pary;
}
public String getParz() {
return parz;
}
public void setParz(String parz) {
this.parz = parz;
}
}
It should work
As a side note:
Gson uses LinkedLIst when Jackson ArrayList therefore from your code Gson fail to convert Passes class
I have an SQL statement with the names of the class instead of the names of the tables.
Then I use a ResultTransformer to map the result in a bean, but Hibernate does not transform the query(with the classes) in a query capable for Oracle.
The code is like this:
Session sx = hibernateTemplate.getSessionFactory().openSession();
SQLQuery q = sx.createSQLQuery(queryUser);
sottoInterventiPagatiList = (List<SottoInterventiPagatiBean>)q.setResultTransformer(Transformers.aliasToBean(SottoInterventiPagatiBean.class)).list();
the query is:
select pagaSott.codiSequPagaSottInte as codiSequPagaSottInte,
pagaSott.impoSostSottInte as impoSostSottInte,
pagaSott.impoRichSottInte as impoRichSottInte,
pagaSott.impoAcceSottInte as impoAcceSottInte,
pagaSott.impoAmmeSottInte as impoAmmeSottInte,
pagaSott.codiSottTipo as codiSottTipo,
pagaInte.tabAgriPsrClTipoInt.codiTipo as codiTipo,
ammiDomaAiut.descSottTipo as descSottTipo,
ammiDomaAiut.impoSpesTotaAmme as impoSpesTotaAmme,
ammiDomaAiut.impoTotaAmme as impoTotaAmme
from AmmissibilitaDomandaAiuto ammiDomaAiut,
PagamentiDoma pagaDoma,
PagaInte pagaInte, PagaSottInte pagaSott
where pagaDoma.codiDomaAiut = ammiDomaAiut.domandaByCodiDomaAiut.codiDoma
and pagaDoma.tabAgriPsrClMisure.codiMisu = ammiDomaAiut.misure.codiMisu
and pagaInte.tabAgriPsrPagamentiDoma.codiSequPagaDoma = pagaDoma.codiSequPagaDoma
and pagaInte.tabAgriPsrClTipoInt.codiTipo = ammiDomaAiut.tipiIntervento.codiTipo
and pagaSott.tabAgriPsrPagaInte.codiSequPagaInte = pagaInte.codiSequPagaInte
and pagaSott.codiSottTipo = ammiDomaAiut.sottoTipiIntervento.codiSottTipo
and ammiDomaAiut.domandaByCodiDomaAiut.codiDoma = 13
and ammiDomaAiut.misure.codiMisu = 6
the bean is:
public class SottoInterventiPagatiBean implements Serializable{
private static final long serialVersionUID = -1831093835824406823L;
private Integer codiSequPagaSottInte;
private Integer codiTipo;
private BigDecimal codiSottTipo;
private String descSottTipo;
private BigDecimal impoSostSottInte;
private BigDecimal impoRichSottInte;
private BigDecimal impoAcceSottInte;
private BigDecimal impoAmmeSottInte;
private BigDecimal impoSpesTotaAmme;
private BigDecimal impoTotaAmme;
public Integer getCodiSequPagaSottInte() {
return codiSequPagaSottInte;
}
public void setCodiSequPagaSottInte(Integer codiSequPagaSottInte) {
this.codiSequPagaSottInte = codiSequPagaSottInte;
}
public Integer getCodiTipo() {
return codiTipo;
}
public void setCodiTipo(Integer codiTipo) {
this.codiTipo = codiTipo;
}
public BigDecimal getCodiSottTipo() {
return codiSottTipo;
}
public void setCodiSottTipo(BigDecimal codiSottTipo) {
this.codiSottTipo = codiSottTipo;
}
public String getDescSottTipo() {
return descSottTipo;
}
public void setDescSottTipo(String descSottTipo) {
this.descSottTipo = descSottTipo;
}
public BigDecimal getImpoSostSottInte() {
return impoSostSottInte;
}
public void setImpoSostSottInte(BigDecimal impoSostSottInte) {
this.impoSostSottInte = impoSostSottInte;
}
public BigDecimal getImpoRichSottInte() {
return impoRichSottInte;
}
public void setImpoRichSottInte(BigDecimal impoRichSottInte) {
this.impoRichSottInte = impoRichSottInte;
}
public BigDecimal getImpoAcceSottInte() {
return impoAcceSottInte;
}
public void setImpoAcceSottInte(BigDecimal impoAcceSottInte) {
this.impoAcceSottInte = impoAcceSottInte;
}
public BigDecimal getImpoAmmeSottInte() {
return impoAmmeSottInte;
}
public void setImpoAmmeSottInte(BigDecimal impoAmmeSottInte) {
this.impoAmmeSottInte = impoAmmeSottInte;
}
public BigDecimal getImpoSpesTotaAmme() {
return impoSpesTotaAmme;
}
public void setImpoSpesTotaAmme(BigDecimal impoSpesTotaAmme) {
this.impoSpesTotaAmme = impoSpesTotaAmme;
}
public BigDecimal getImpoTotaAmme() {
return impoTotaAmme;
}
public void setImpoTotaAmme(BigDecimal impoTotaAmme) {
this.impoTotaAmme = impoTotaAmme;
}
}
Use session.createQuery(...) instead of createSQLQuery(...). createSQLQuery creates an SQL query, hibernate assumes that your query is already in sql format, then no other transformation is done.