I have used One-to-Many Mapping in my project. I have stored a list of clicks for every user.
But when I retrieve the list by calling getClicks() methodm Hibernate returns list in different format.
Something like this.
"[com.zednx.tech.persistence.Click#29df9a77]"
So I tried Reading Every value from the list and assign to a new List.
List<Click> clicks=new ArrayList<Click>();
for(Click c: e.getClicks()){
Click temp = new Click();
temp.setAff_source(c.getAff_source());
temp.setCb_to_award(c.getCb_to_award());
temp.setCb_type(c.getCb_type());
clicks.add(temp);
}
But when i print the items of new List it stills prints the same way.
I need to build a JSON from the resulting String of this list.
So if the list is returned in format, it wont help me.
I couldn't find anything regarding this except How to pretty print Hibernate query results?
I tried Arrays.ToString(Object o). But it doesn't work.
GSON builder part-
Gson gson = new GsonBuilder()
.registerTypeAdapter(Click.class, new MyTypeAdapter<Click>())
.create();
List<Click> clicks=new ArrayList<Click>();
for(Click c: e.getClicks()){
Click temp = new Click();
temp.setAff_source(c.getAff_source());
temp.setCb_to_award(c.getCb_to_award());
temp.setCb_type(c.getCb_type());
temp.setCom_to_recieve(c.getCom_to_recieve());
temp.setStore_name(c.getStore_name());
temp.setT_date(c.getT_date());
temp.setT_status(c.getT_status());
temp.setT_ticket(c.getT_ticket());
temp.setUid(c.getUid());
System.out.println(c.toString());
clicks.add(temp);
}
String json = gson.toJson(clicks, Click.class);
Click.java
#Entity
#Table(name="click")
public class Click {
#Id
#Column(name="t_ticket")
private String t_ticket;
#Column(name="uid",nullable=false)
private long uid;
public long getUid() {
return uid;
}
public void setUid(long uid) {
this.uid = uid;
}
#ManyToOne
#JoinColumn(name="uid",
insertable=false, updatable=false,
nullable=false)
private Earning earning;
#Column(name="store_name")
private String store_name;
#Column(name="t_status")
private String t_status;
#Column(name="aff_source")
private String aff_source;
#Column(name="com_to_recieve")
private float com_to_recieve;
#Column(name="t_date")
private Date t_date;
#Column(name="cb_to_award")
private float cb_to_award;
#Column(name="cb_type")
private String cb_type;
public String getT_ticket() {
return t_ticket;
}
public void setT_ticket(String t_ticket) {
this.t_ticket = t_ticket;
}
public Earning getEarning() {
return earning;
}
public void setEarning(Earning earning) {
this.earning = earning;
}
public String getStore_name() {
return store_name;
}
public void setStore_name(String store_name) {
this.store_name = store_name;
}
public String getT_status() {
return t_status;
}
public void setT_status(String t_status) {
this.t_status = t_status;
}
public String getAff_source() {
return aff_source;
}
public void setAff_source(String aff_source) {
this.aff_source = aff_source;
}
public float getCom_to_recieve() {
return com_to_recieve;
}
public void setCom_to_recieve(float com_to_recieve) {
this.com_to_recieve = com_to_recieve;
}
public Date getT_date() {
return t_date;
}
public void setT_date(Date t_date) {
this.t_date = t_date;
}
public float getCb_to_award() {
return cb_to_award;
}
public void setCb_to_award(float cb_to_award) {
this.cb_to_award = cb_to_award;
}
public String getCb_type() {
return cb_type;
}
public void setCb_type(String cb_type) {
this.cb_type = cb_type;
}
Any Help is appreciated.
You need to implement a toString method, as your current Click class likely doesn't have one, so it just prints as the name of the class and instance identifier.
Okay, I could solve my problem finally.
I made another POJO without any annotations and Mapped the List items to that POJO class.
I think the problem was with Annotation of mapping on another class which I had in original POJO.
Also getString() method only helps in changing format of identifier. So basically it has nothing to do with JSON building unless you format getString() in form of JSON.
Hope it helps. If anyone wants new temp POJO I made I can post it if requested.
Thanks.
Related
My PoIs class:
public class PoIs {
private Integer location_id;
private String location_name;
private String location_address;
public PoIs() {}
public PoIs(Integer location_id, String location_name, String location_address) {
this();
this.location_id = location_id;
this.category_id = category_id;
this.location_name = location_name;
this.location_address = location_address;
}
public Integer get_location_id() {
return location_id;
}
public void set_location_id(Integer location_id) {
this.location_id = location_id;
}
public String get_location_name() {
return location_name;
}
public void set_location_name(String location_name) {
this.location_name = location_name;
}
public String get_location_address() {
return location_address;
}
public void set_location_address(String location_address) {
this.location_address = location_address;
}
I populate PoIs with informatision from a sqlite database:
final PoIs p = new PoIs(Integer.parseInt(row.get(0).toString()), row.get(1).toString(), row.get(2).toString());
and at a moment intend to save them on a firabase database:
FIREBASE_REFERENCE.child("PoI_"+ p.get_location_id()).setValue(p)
.addOnCompleteListener(t -> {
final boolean isSuccessful = t.isSuccessful();
final String msg = !isSuccessful
? getResources().getString(R.string.fb_error)
: getResources().getString(R.string.fb_success);
});
All work perfect except that my firebase fields start with an underscore. Instead location_id, location_name, location_address I have _location_id, _location_name, _location_address. I can't understand why this happening. Any ideea how to resolve this issue?
Firebase uses JavaBean naming conventions when mapping from properties in your code to properties in the database. In that convention a method like get_location_name is the getter for a property called _location_name.
If you want the property in the database to be location_name, that'd be a getter getLocation_name. Alternatively, you can use a #PropertyName("location_name")) annotation on all accessors (so the getter/setter function and/or the public field) to indicate the explicit property name you want in the database.
My Enum type ProductType is properly saving to XML but it doesn't want to unmarshal when opening the file.
I made EnumAdapter:
public class EnumAdapter extends XmlAdapter<String, ProductType>
{
#Override
public ProductType unmarshal(String value) throws Exception {
try {
return ProductType.valueOf(value);
}
catch(Exception e) {
throw new JAXBException(e);
}
}
#Override
public String marshal(ProductType value) {
return value.toString();
}
}
My Product class:
public class Product {
private final IntegerProperty ilosc; //quantity
private final StringProperty nazwa; //name
private final ObjectProperty<ProductType> typ; //type
private final BooleanProperty dostepnosc;
public Product()
{
this(null, 0, ProductType.ALKOHOL, true);
}
public Product(String nazwa, int ilosc, ProductType typ, boolean dostepnosc) {
this.nazwa = new SimpleStringProperty(nazwa);
this.ilosc = new SimpleIntegerProperty(ilosc);
this.typ = new SimpleObjectProperty<>(typ);
this.dostepnosc = new SimpleBooleanProperty(dostepnosc);
}
.
.
.
#XmlJavaTypeAdapter(EnumAdapter.class)
public ProductType getTyp() {
return typ.get();
}
After opening the XML in my app enum is always setting to the value from default constructor (which is ALCOHOL, if I change it, enum is setting to whatever it is). I also know that marshalling from EnumAdapter works properly, I can change it to whatever I want. Please help.
I solved it, I was missing proper setting function:
public void setTyp(ProductType type){
this.typ.setValue(type);
I have a couple of objects from which selected members should be combined to create an output object. All these are POJOs. I am seeing that all object mappers work on a single POJO to another POJO level. Is there any mapper that supports what I am looking for? Of course, I understand that there is some mapping stuff that I need to specify.
Edit:
I know how to get this done by writings own Java class. I am just looking for a way to do it with one of the mapping libraries.
You aren't limited in what you require to be passed to your mapper. You can define it to accept several items and build the object based on the multiple inputs. Here is an example:
public class ClassOne {
private final String someProperty;
public ClassOne(String someProperty) {
this.someProperty = someProperty;
}
public String getSomeProperty() {
return someProperty;
}
}
public class ClassTwo {
private final String someOtherProperty;
public ClassTwo(String someOtherProperty) {
this.someOtherProperty = someOtherProperty;
}
public String getSomeOtherProperty() {
return someOtherProperty;
}
}
public class CombinedClass {
public static CombinedClass mapper(ClassOne one, ClassTwo two){
return new CombinedClass(one.getSomeProperty(), two.getSomeOtherProperty());
}
private final String someProperty;
private final String someOtherProperty;
private CombinedClass(String someProperty, String someOtherProperty) {
this.someProperty = someProperty;
this.someOtherProperty = someOtherProperty;
}
public String getSomeProperty() {
return someProperty;
}
public String getSomeOtherProperty() {
return someOtherProperty;
}
}
I am serializing Diagram class to GAE Datastore using Objectify. I can update (serialize) all the fields as many times as I want, except Integer arrowTypeId, that is only updated once, and after that keeps always the same value. If I leave the app and run it again, I can update again that value, but only once.
To update arroyTypeId I am calling sendDatabaseUpdateDiagramArrows(). This is what happens:
I call sendDatabaseUpdateDiagramArrows() with value 1
I set that value to the DiagramProxy.setArrowTypeId().
As a test, I change the diagram title to DiagramProxy.getArrowTypeId()
I call save()
On the DAO save(), the wrong value of ArrowTypeId is received (keeps the old one), but surprisingly, the Title has the right ArrowTypeId stored from step 3)
Changes are serialized with this problem. No exceptions are displayed.
Note that I am able to update ArrowTypeId value the first time, from default value 1 to 2. Buth the next time keeps always value 2.
Edit: If I change arrowTypeId to a String, I have the same issue.
DatabaseUtils.java
public static DiagramProxy sendDatabaseUpdateDiagramArrows(DialectiveRequestFactory requestFactory, Integer value, DiagramProxy cellDiagramProxy)
{
DiagramRequest diagramRequest = requestFactory.diagramRequest();
DiagramProxy newDiagramProxy = diagramRequest.edit(cellDiagramProxy);
Date date = new Date();
newDiagramProxy.setArrowTypeId(value);
newDiagramProxy.setTitle(Integer.toString(newDiagramProxy.getArrowTypeId()));
diagramRequest.save(newDiagramProxy).fire();
return cellDiagramProxy;
}
Diagram.java
#Entity
public class Diagram extends DatastoreObject{
#Indexed private String diagramId;
private String title;
private Integer arrowTypeId;
public String get_id() {
return diagramId;
}
public void set_id(String diagramId) {
this.diagramId = diagramId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Integer getArrowTypeId() {
return arrowTypeId;
}
public void setArrowTypeId(Integer arrowTypeId) {
this.arrowTypeId = arrowTypeId;
}
}
DiagramProxy.java
#ProxyFor(value = Diagram.class, locator = ObjectifyLocator.class)
public interface DiagramProxy extends EntityProxy{
void set_id(String id);
void setTitle(String title);
void setArrowTypeId(Integer arrowTypeId);
Integer getArrowTypeId();
String get_id();
String getTitle();
}
DiagramDao.java
public class DiagramDao extends ObjectifyDao<Diagram>{
public void save(Diagram diagram)
{
this.put(diagram);
} }
Let me guess :) as I don't have experience with GAE datastore.
I don't get the point, why you make
#Indexed private String diagramId;
but getter and setter with non-standard names:
public String get_id() {
return diagramId;
}
public void set_id(String diagramId) {
this.diagramId = diagramId;
}
I'd rather go for:
#Indexed private String diagramId;
public String getDiagramId() {
return diagramId;
}
public void setDiagramId(String diagramId) {
this.diagramId = diagramId;
}
One more thing is that DiagramRequest code has not been published, maybe that could help in seeing the problem.
I want to marshal/unmarshal 2 custom types. And the type 1 has a List. Marshalling works as expected - I see a separate element for every type2 element in the list, but when I try to unmarshal it this doesn't work.
Workflow
#XmlRootElement
public class Workflow {
private String userEmail;
private List<WorkflowStep> steps = new ArrayList<WorkflowStep>(5);
//required by jaxb
public Workflow() {
}
public void setSteps(List<WorkflowStep> steps) {
this.steps = steps;
}
public List<WorkflowStep> getSteps() {
//do a defensive copy
return new ArrayList<WorkflowStep>(steps);
}
public void setUserEmail(String email) {
userEmail = email;
}
public String getUserEmail() {
return userEmail;
}
}
WorkflowStep
#XmlRootElement
public class WorkflowStep {
private int cpu = 1;
private int mem = 1000;
private Map<String, String> parameters = Collections.emptyMap();
public WorkflowStep() {
}
public void setCpu(int numCores) {
cpu = numCores;
}
public int getCpu() {
return cpu;
}
public void setMem(int mb) {
mem = mb;
}
public int getMem() {
return mem;
}
}
Here is an example output if I access the web service from a browser:
<workflow>
<steps>
<cpu>1</cpu>
<inputId>237</inputId>
<mem>1000</mem>
<parameters/>
<status>NOT-YET-STARTED</status>
<stepId>1509</stepId>
<submoduleId>0</submoduleId>
<workflowId>797</workflowId>
</steps>
<steps>
<cpu>1</cpu>
<inputId>364</inputId>
<mem>1000</mem>
<parameters/>
<status>NOT-YET-STARTED</status>
<stepId>1510</stepId>
<submoduleId>3</submoduleId>
<workflowId>797</workflowId>
</steps>
<userEmail>foo#bar.com</userEmail>
<workflowId>797</workflowId>
<workflowName>test-name</workflowName>
</workflow>
WorkflowStep is marshalled/unmarshalled successfully but a List cannot be unmarshalled why is that? Nor the application server, nor the REST client receive any errors or exceptions, the client just ignores the list of WorkflowSteps? From the above example output I'd expect that every element would be converted into an object of type WorkflowStep and then will automatically be added to the List?
The problem is with this method:
public List<WorkflowStep> getSteps() {
//do a defensive copy
return new ArrayList<WorkflowStep>(steps);
}
Your JAXB implementation checks if there is already a List for this method, and if there is it uses it. The List you are returning is not held by the object you are unmarshalling, so after the unmarshal operation the List is lost.
Option #1 - Change the getSteps() Method
public List<WorkflowStep> getSteps() {
//don't do a defensive copy
return steps;
}
Option #2 - Use Field Access
You could change this your specify that JAXB should use field access.
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Workflow {
...
}
For more information
http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html