public class Media implements java.io.Serializable {
private int id;
private MediaKind mediaKind;
private String name;
private byte[] cover;
private Date releaseDate;
private Integer contentRating;
private String summary;
private Set mediaCrews = new HashSet(0);
private Set mediaInstances = new HashSet(0);
private Set ratings = new HashSet(0);
private Set genres = new HashSet(0);
static SessionFactory mediaFactory=Main.config.buildSessionFactory();
public Media() {
}
public Media(int id, MediaKind mediaKind, String name) {
this.id = id;
this.mediaKind = mediaKind;
this.name = name;
Session mediaSession = mediaFactory.getCurrentSession();
}
public Media(int id, MediaKind mediaKind, String name, byte[] cover,
Date releaseDate, Integer contentRating, String summary,
Set mediaCrews, Set mediaInstances, Set ratings, Set genres) {
this.id = id;
this.mediaKind = mediaKind;
this.name = name;
this.cover = cover;
this.releaseDate = releaseDate;
this.contentRating = contentRating;
this.summary = summary;
this.mediaCrews = mediaCrews;
this.mediaInstances = mediaInstances;
this.ratings = ratings;
this.genres = genres;
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public MediaKind getMediaKind() {
return this.mediaKind;
}
public void setMediaKind(MediaKind mediaKind) {
this.mediaKind = mediaKind;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public byte[] getCover() {
return this.cover;
}
public void setCover(byte[] cover) {
this.cover = cover;
}
public Date getReleaseDate() {
return this.releaseDate;
}
public void setReleaseDate(Date releaseDate) {
this.releaseDate = releaseDate;
}
public Integer getContentRating() {
return this.contentRating;
}
public void setContentRating(Integer contentRating) {
this.contentRating = contentRating;
}
public String getSummary() {
return this.summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public Set getMediaCrews() {
return this.mediaCrews;
}
public void setMediaCrews(Set mediaCrews) {
this.mediaCrews = mediaCrews;
}
public Set getMediaInstances() {
return this.mediaInstances;
}
public void setMediaInstances(Set mediaInstances) {
this.mediaInstances = mediaInstances;
}
public Set getRatings() {
return this.ratings;
}
public void setRatings(Set ratings) {
this.ratings = ratings;
}
public Set getGenres() {
return this.genres;
}
public void setGenres(Set genres) {
this.genres = genres;
}
public static java.util.List<Media> search(String name){
java.util.List list;
Session sess=mediaFactory.getCurrentSession();
sess.beginTransaction();
Criteria criteria=sess.createCriteria(Media.class);
criteria.add(Restrictions.like("name", "%"+name+"%"));
list= criteria.list();
Hibernate.initialize(list);
sess.getTransaction().commit();
//connection=sess.close();
return list;
}
public ArrayList<MediaInstance> availableInstances(){
//sess.beginTransaction();
Session sess=mediaFactory.openSession();
sess.beginTransaction();
Criteria criteria=sess.createCriteria(MediaInstance.class);
criteria.add(Restrictions.like("media", name));
sess.getTransaction().commit();
return (ArrayList<MediaInstance>)criteria.list();
/*MediaInstance[] instances=(MediaInstance[]) mediaInstances.toArray();
ArrayList<MediaInstance> mediaInstanceList=new ArrayList<MediaInstance>(Arrays.asList(instances));
for(int i=0;i<mediaInstanceList.size();i++){
MediaInstance instance=mediaInstanceList.get(i);
if(!instance.isAvailable()|!instance.isSellable()){
mediaInstanceList.remove(instance);
}
}
//sess.getTransaction().commit();
//sess.close();
return mediaInstanceList;*/
}
}
here is my second class mediaInstance:
public class MediaInstance implements java.io.Serializable {
private int id;
private MediaType mediaType;
private Media media;
private String price;
private boolean available;
private boolean sellable;
private Set rents = new HashSet(0);
private Set purchases = new HashSet(0);
public MediaInstance() {
}
public MediaInstance(int id, MediaType mediaType, Media media,
String price, boolean available, boolean sellable) {
this.id = id;
this.mediaType = mediaType;
this.media = media;
this.price = price;
this.available = available;
this.sellable = sellable;
}
public MediaInstance(int id, MediaType mediaType, Media media,
String price, boolean available, boolean sellable, Set rents,
Set purchases) {
this.id = id;
this.mediaType = mediaType;
this.media = media;
this.price = price;
this.available = available;
this.sellable = sellable;
this.rents = rents;
this.purchases = purchases;
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public MediaType getMediaType() {
return this.mediaType;
}
public void setMediaType(MediaType mediaType) {
this.mediaType = mediaType;
}
public Media getMedia() {
return this.media;
}
public void setMedia(Media media) {
this.media = media;
}
public String getPrice() {
return this.price;
}
public void setPrice(String price) {
this.price = price;
}
public boolean isAvailable() {
return this.available;
}
public void setAvailable(boolean available) {
this.available = available;
}
public boolean isSellable() {
return this.sellable;
}
public void setSellable(boolean sellable) {
this.sellable = sellable;
}
public Set getRents() {
return this.rents;
}
public void setRents(Set rents) {
this.rents = rents;
}
public Set getPurchases() {
return this.purchases;
}
public void setPurchases(Set purchases) {
this.purchases = purchases;
}
}
When I try to call criteria.list() in method availableInstances() I get this exception.
May 27, 2014 1:22:56 PM org.hibernate.property.BasicPropertyAccessor$BasicGetter get
ERROR: HHH000122: IllegalArgumentException in class: Media, getter method of property: id
Exception in thread "main" org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of Media.id
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:192)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:346)
at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:4746)
at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:4465)
at org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:243)
at org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:293)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:537)
at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:174)
at org.hibernate.loader.Loader.bindPositionalParameters(Loader.java:1994)
at org.hibernate.loader.Loader.bindParameterValues(Loader.java:1965)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1900)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1861)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1838)
at org.hibernate.loader.Loader.doQuery(Loader.java:909)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354)
at org.hibernate.loader.Loader.doList(Loader.java:2553)
at org.hibernate.loader.Loader.doList(Loader.java:2539)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2369)
at org.hibernate.loader.Loader.list(Loader.java:2364)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:126)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1682)
at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:380)
at MediaInstance.availableInstances(MediaInstance.java:125)
at Main.main(Main.java:24)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:169)
... 23 more
I used JBoss tools to generate the classes and mapping files from my database.
so I don't think that the problem is in mapping files.
Your criteria query doesn't seem right. You are trying to filter by an instance of media entity but passing the name as parameter.
Try something like this:
criteria.add(Restrictions.eq("media", this));
The second argument passed to the static "like" method (or "eq" method, and so on) of the Restrictions static class must be of the same type of the field identified by the first string (first argument).
In your example:
criteria.add(Restrictions.like("media", name));
"name" is a String while "media" field of the MediaInstance class is a instance of Media. You should substitute "name" with a media instance, even the Media instance itself executing the "availableInstances" method, so:
criteria.add(Restrictions.like("media", this));
Related
I am using Spring Boot (v 2.4.0) with Hibernate 5.4.24 and, when trying to get some information from my database, I keep getting this error message:
org.springframework.orm.jpa.JpaSystemException: Error accessing field [private int es.uc3m.orders.model.Shoppingcart.usID] by reflection for persistent property [es.uc3m.orders.model.Shoppingcart#usID] : 1; nested exception is org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private int es.uc3m.orders.model.Shoppingcart.usID] by reflection for persistent property [es.uc3m.orders.model.Shoppingcart#usID] : 1
It is kind of weird for me, because it only happens when I try to access the table Shoppingcart, since I can get informatin from the rest of the tables.
I also used the exact same entities with another project but, insetad of using Spring Boot, persistence was made with EntityManagers and it worked perfectly fine.
These are my entities:
Shoppingcart
#Entity
#NamedQuery(name="Shoppingcart.findAll", query="SELECT s FROM Shoppingcart s")
public class Shoppingcart implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int scID;
private int usID;
//bi-directional many-to-many association to Product
#ManyToMany
#JoinTable(
name="sc_has_product"
, joinColumns={
#JoinColumn(name="scID")
}
, inverseJoinColumns={
#JoinColumn(name="productID")
}
)
private List<Product> products;
//bi-directional one-to-one association to User
#OneToOne(mappedBy="shoppingcart")
private User user;
public Shoppingcart() {
}
public int getScID() {
return this.scID;
}
public void setScID(int scID) {
this.scID = scID;
}
public int getusID() {
return this.usID;
}
public void setusID(int usID) {
this.usID = usID;
}
public List<Product> getProducts() {
return this.products;
}
public void setProducts(List<Product> products) {
this.products = products;
}
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
public boolean isNull() {
return getProducts().isEmpty();
}
User
#Entity
#Table(name="users")
#NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String address;
#Column(name="card_n")
private Long cardN;
private String city;
private String country;
private int cvv;
private String email;
private String exp;
private String name;
private String pass;
private String surname1;
private String surname2;
private String typeOfUser;
#Column(name="zip_code")
private int zipCode;
//bi-directional many-to-one association to Order
#OneToMany(mappedBy="user")
private List<Orders> orders;
//bi-directional many-to-one association to Product
#OneToMany(mappedBy="user")
private List<Product> products;
//bi-directional one-to-one association to Shoppingcart
#OneToOne(cascade=CascadeType.REMOVE)
#JoinColumn(name="ID", referencedColumnName="usID", insertable=false, updatable=false)
private Shoppingcart shoppingcart;
public User() {
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
public Long getCardN() {
return this.cardN;
}
public void setCardN(Long cardN) {
this.cardN = cardN;
}
public String getCity() {
return this.city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return this.country;
}
public void setCountry(String country) {
this.country = country;
}
public int getCvv() {
return this.cvv;
}
public void setCvv(int cvv) {
this.cvv = cvv;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getExp() {
return this.exp;
}
public void setExp(String exp) {
this.exp = exp;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return this.pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getSurname1() {
return this.surname1;
}
public void setSurname1(String surname1) {
this.surname1 = surname1;
}
public String getSurname2() {
return this.surname2;
}
public void setSurname2(String surname2) {
this.surname2 = surname2;
}
public int getZipCode() {
return this.zipCode;
}
public void setZipCode(int zipCode) {
this.zipCode = zipCode;
}
public List<Orders> getOrders() {
return this.orders;
}
public void setOrders(List<Orders> orders) {
this.orders = orders;
}
public Orders addOrder(Orders order) {
getOrders().add(order);
order.setUser(this);
return order;
}
public Orders removeOrder(Orders order) {
getOrders().remove(order);
order.setUser(null);
return order;
}
public List<Product> getProducts() {
return this.products;
}
public void setProducts(List<Product> products) {
this.products = products;
}
public Product addProduct(Product product) {
getProducts().add(product);
product.setUser(this);
return product;
}
public Product removeProduct(Product product) {
getProducts().remove(product);
product.setUser(null);
return product;
}
public Shoppingcart getShoppingcart() {
return this.shoppingcart;
}
public void setShoppingcart(Shoppingcart shoppingcart) {
this.shoppingcart = shoppingcart;
}
public String getTypeOfUser() {
return typeOfUser;
}
public void setTypeOfUser(String typeOfUser) {
this.typeOfUser = typeOfUser;
}
}
This is the ShoppingcartDAO class:
public interface ShoppingCartDAO extends CrudRepository<Shoppingcart, Integer> {
#Query("SELECT s FROM Shoppingcart s JOIN User u ON u.id = s.usID AND u.id LIKE :id")
Shoppingcart findByUser(#Param("id") int id);
#Query("SELECT s FROM Shoppingcart s")
List<Shoppingcart> findAllShoppingCart();
}
And, finally, this is my ShoppingcartController class:
#RestController
#CrossOrigin
#EnableAutoConfiguration
public class ShoppingCartController {
#Autowired
ShoppingCartDAO scDAO;
#RequestMapping(value = "sc", method = RequestMethod.POST, produces = "application/json")
public ResponseEntity<?> assignShoppingCart(#RequestBody(required = true) Shoppingcart sc) {
try {
scDAO.save(sc);
return new ResponseEntity<Void>(HttpStatus.CREATED);
} catch(Exception e) {
return new ResponseEntity<Void>(HttpStatus.BAD_REQUEST);
}
}
#RequestMapping(value = "sc", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<?> getEveryShoppingCart() {
try {
List<Shoppingcart> sc = scDAO.findAllShoppingCart();
return new ResponseEntity<List<Shoppingcart>>(sc, (sc != null) ? HttpStatus.OK : HttpStatus.NOT_FOUND);
} catch(Exception e) {
System.out.println(e);
return new ResponseEntity<Void>(HttpStatus.BAD_REQUEST);
}
}
}
I am really going nuts as I canĀ“t figure out what is going on with my code, so thank you in advance if you help me.
I finally fixed it. For those of you who are wondering how, I deleted the relationships between tables that I had, ending with:
Shoppingcart:
#Entity
public class Shoppingcart implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int scID;
#Column(name = "usID")
private Integer userID;
public Shoppingcart() {
}
public int getScID() {
return this.scID;
}
public void setScID(int scID) {
this.scID = scID;
}
public Integer getUserID() {
return userID;
}
public void setUserID(Integer userID) {
this.userID = userID;
}
Product:
#Entity
public class Product implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int productID;
private String category;
private String color;
private String description;
private String estadoProducto;
private String fecha;
private int orderID;
private String photo;
private double price;
private int seller;
private String sexo;
private String state = "Disponible";
private String talla;
private String title;
public Product() {
}
public int getProductID() {
return this.productID;
}
public void setProductID(int productID) {
this.productID = productID;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getColor() {
return this.color;
}
public void setColor(String color) {
this.color = color;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public String getEstadoProducto() {
return this.estadoProducto;
}
public void setEstadoProducto(String estadoProducto) {
this.estadoProducto = estadoProducto;
}
public String getFecha() {
return this.fecha;
}
public void setFecha(String fecha) {
this.fecha = fecha;
}
public String getPhoto() {
return this.photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
public double getPrice() {
return this.price;
}
public void setPrice(double price) {
this.price = price;
}
public String getSexo() {
return this.sexo;
}
public void setSexo(String sexo) {
this.sexo = sexo;
}
public String getState() {
return this.state;
}
public void setState(String state) {
this.state = state;
}
public String getTalla() {
return this.talla;
}
public void setTalla(String talla) {
this.talla = talla;
}
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public int getOrderID() {
return orderID;
}
public void setOrderID(int orderID) {
this.orderID = orderID;
}
public int getSeller() {
return seller;
}
public void setSeller(int seller) {
this.seller = seller;
}
With this, everything worked fine, but don't ask me why, because I don't know it.
Your Getters/Setters are wrongly implemented.
Like :
Actual :
public int getusID() {
return this.usID;
}
Expected :
public int getUsID() {
return this.usID;
}
Same with setter
I am just creating a handler in java which accepts a POJO called as ProductsModel.
public ProductsResponseObject handleRequest(ProductsRequestObject productsRequestObject, Context arg1) {
ProductsResponseObject respObj = null;
ProductsService productsService = new ProductsService();
arg1.getLogger().log("inside ProductsHandler.handleRequest with reqtype " + productsRequestObject.getReqType());
switch (productsRequestObject.getReqType()) {
case 0:
respObj = productsService.addProduct(productsRequestObject);
break;
case 1:
respObj = productsService.updateProduct(productsRequestObject);
break;
default:
break;
}
return respObj;
}
But here inside the handler method, the attributes of request, reqType and productModel are null. Not sure y?
Request POJO:
public class ProductsRequestObject {
private int reqType;
private ProductsModel productsModel;
public int getReqType() {
return reqType;
}
public void setReqType(int reqType) {
this.reqType = reqType;
}
public ProductsModel getProductsModel() {
return productsModel;
}
public void setProductsModel(ProductsModel productsModel) {
this.productsModel = productsModel;
}
}
Model POJO:
public class ProductsModel {
private String id;
private String dealerMobNumber;
private String name;
private String description;
private String price;
#DynamoDBHashKey(attributeName = "Id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDealerMobNumber() {
return dealerMobNumber;
}
public void setDealerMobNumber(String dealerMobNumber) {
this.dealerMobNumber = dealerMobNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
I am using Flickr API to get the information of images and returns the following JSON:
{"photos":{"page":1,"pages":60,"perpage":100,"total":"5964","photo":[{"id":"21577339501","owner":"85277110#N02","secret":"31e850dfeb","server":"5785","farm":6,"title":"P1390956","ispublic":1,"isfriend":0,"isfamily":0}, {"id":"21577287101","owner":"85277110#N02","secret":"412990658f","server":"611","farm":1,"title":"P1400012","ispublic":1,"isfriend":0,"isfamily":0}]
I use this code in the Spring controller to deserialize the JSON:
Collection<Photos> readValues = objectMapper.readValue(new URL(url), new TypeReference<Collection<Photos>>() { });
And returns the following error:
com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
How can I solve this problem? I didn't found solutions.
Photos.class:
public class Photos {
#JsonProperty("page")
private Integer page;
#JsonProperty("pages")
private Integer pages;
#JsonProperty("perpage")
private Integer perpage;
#JsonProperty("total")
private Integer total;
#JsonProperty("photo")
#JsonDeserialize(contentAs = Photo.class, as = ArrayList.class)
private List<Photo> photo;
public Photos() {}
public Photos(Integer page, Integer pages, Integer perpage, Integer total,
List<Photo> photo) {
super();
this.page = page;
this.pages = pages;
this.perpage = perpage;
this.total = total;
this.photo = photo;
}
public Photos(List<Photo> photo) {
super();
this.photo = photo;
}
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
this.page = page;
}
public Integer getPages() {
return pages;
}
public void setPages(Integer pages) {
this.pages = pages;
}
public Integer getPerpage() {
return perpage;
}
public void setPerpage(Integer perpage) {
this.perpage = perpage;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public List<Photo> getPhoto() {
return photo;
}
public void setPhoto(List<Photo> photo) {
this.photo = photo;
}
}
Photo.class:
public class Photo {
#JsonProperty("id")
private Integer id;
#JsonProperty("owner")
private String owner;
#JsonProperty("secret")
private String secret;
#JsonProperty("server")
private Integer server;
#JsonProperty("farm")
private Integer farm;
#JsonProperty("title")
private String title;
#JsonProperty("ispublic")
private Boolean isPublic;
#JsonProperty("isfriend")
private Boolean isFriend;
#JsonProperty("isfamily")
private Boolean isFamily;
public Photo() { }
public Photo(Integer id, String owner, String secret, Integer server,
Integer farm, String title, Boolean isPublic, Boolean isFriend,
Boolean isFamily) {
super();
this.id = id;
this.owner = owner;
this.secret = secret;
this.server = server;
this.farm = farm;
this.title = title;
this.isPublic = isPublic;
this.isFriend = isFriend;
this.isFamily = isFamily;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public Integer getServer() {
return server;
}
public void setServer(Integer server) {
this.server = server;
}
public Integer getFarm() {
return farm;
}
public void setFarm(Integer farm) {
this.farm = farm;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Boolean getIsPublic() {
return isPublic;
}
public void setIsPublic(Boolean isPublic) {
this.isPublic = isPublic;
}
public Boolean getIsFriend() {
return isFriend;
}
public void setIsFriend(Boolean isFriend) {
this.isFriend = isFriend;
}
public Boolean getIsFamily() {
return isFamily;
}
public void setIsFamily(Boolean isFamily) {
this.isFamily = isFamily;
}
}
The basic problem is that your json is not a Collection<Photos>, but a Map<String, Photos>, which has a single entry "photos" -> Photos instance.
I got your json to successfully deserialize by making the following changes...
A) Change the type being read:
Map<String, Photos> readValues = objectMapper.readValue(json, new TypeReference<Map<String, Photos>>() { });
Note that I read straight from a String (not a URL).
B) Change the type of Photo.id from Integer to Long, because your json has id values well exceeding max int size.
C) I added the missing two closing braces from your sample json to make it valid.
FYI, deserialization works with or without the #JsonDeserialize annotation on the List<Photo> photo field of Photos.
Here's some runnable code that works:
String json = "{\"photos\":{\"page\":1,\"pages\":60,\"perpage\":100,\"total\":\"5964\",\"photo\":[{\"id\":\"21577339501\",\"owner\":\"85277110#N02\",\"secret\":\"31e850dfeb\",\"server\":\"5785\",\"farm\":6,\"title\":\"P1390956\",\"ispublic\":1,\"isfriend\":0,\"isfamily\":0}, {\"id\":\"21577287101\",\"owner\":\"85277110#N02\",\"secret\":\"412990658f\",\"server\":\"611\",\"farm\":1,\"title\":\"P1400012\",\"ispublic\":1,\"isfriend\":0,\"isfamily\":0}]}}";
Map<String, Photos> readValues = new ObjectMapper().readValue(json, new TypeReference<Map<String, Photos>>() { });
I have two classes which implement Parcelable. And objects of one of them I have to write to a list. First model:
public class Challenge implements Parcelable {
private long id;
#JsonProperty("max_volume")
private int maxVolume;
#JsonProperty("current_volume")
private int currentVolume;
private String name;
private String description;
#JsonProperty("max_count")
private int maxCount;
#JsonProperty("date_from")
private Date dateFrom;
#JsonProperty("date_to")
private Date dateTo;
#JsonProperty("create_time")
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm ZZZZ")
private Date createTime;
private ChallengeStatus status;
#JsonProperty("update_date")
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm ZZZZ")
private Date updateTime;
private ChallengeCategory category;
private Subject subject;
private ArrayList<User> userArrayList;
private int practice;
public double getProgress() {
return progress;
}
public void setProgress(double progress) {
this.progress = progress;
}
public int getPractice() {
return practice;
}
public void setPractice(int practice) {
this.practice = practice;
}
private double progress;
public Challenge() {
}
private Creator<User> creator;
protected Challenge(Parcel in) {
id = in.readLong();
maxVolume = in.readInt();
currentVolume = in.readInt();
name = in.readString();
description = in.readString();
maxCount = in.readInt();
// dateFrom = new Date(in.readLong());
// dateTo = new Date(in.readLong());
// createTime = new Date(in.readLong());
// status = ChallengeStatus.getEnum(in.readString());
// updateTime = new Date(in.readLong());
// category = ChallengeCategory.getEnum(in.readString());
subject = in.readParcelable(Subject.class.getClassLoader());
userArrayList = in.readTypedList(userArrayList, User.CREATOR);
}
public static final Creator<Challenge> CREATOR = new Creator<Challenge>() {
#Override
public Challenge createFromParcel(Parcel in) {
return new Challenge(in);
}
#Override
public Challenge[] newArray(int size) {
return new Challenge[size];
}
};
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int getMaxVolume() {
return maxVolume;
}
public void setMaxVolume(int maxVolume) {
this.maxVolume = maxVolume;
}
public int getCurrentVolume() {
return currentVolume;
}
public void setCurrentVolume(int currentVolume) {
this.currentVolume = currentVolume;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getMaxCount() {
return maxCount;
}
public void setMaxCount(int maxCount) {
this.maxCount = maxCount;
}
public Date getDateFrom() {
return dateFrom;
}
public void setDateFrom(Date dateFrom) {
this.dateFrom = dateFrom;
}
public Date getDateTo() {
return dateTo;
}
public void setDateTo(Date dateTo) {
this.dateTo = dateTo;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public ChallengeStatus getStatus() {
return status;
}
public void setStatus(ChallengeStatus status) {
this.status = status;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public ChallengeCategory getCategory() {
return category;
}
public void setCategory(ChallengeCategory category) {
this.category = category;
}
public Subject getSubject() {
return subject;
}
public void setSubject(Subject subject) {
this.subject = subject;
}
#Override
public int describeContents() {
return 0;
}
public ArrayList<User> getUserArrayList() {
return userArrayList;
}
public void setUserArrayList(ArrayList<User> userArrayList) {
this.userArrayList = userArrayList;
}
public static Creator<Challenge> getCREATOR() {
return CREATOR;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(id);
dest.writeInt(maxVolume);
dest.writeInt(currentVolume);
dest.writeString(name);
dest.writeString(description);
dest.writeInt(maxCount);
// dest.writeLong(dateFrom.getTime());
// dest.writeLong(dateTo.getTime());
// dest.writeLong(createTime.getTime());
// dest.writeString(status.toString());
// dest.writeLong(updateTime.getTime());
// dest.writeString(category.toString());
dest.writeParcelable(subject, flags);
dest.writeTypedList(userArrayList);
}
}
And I have a problem at this line: userArrayList = in.readTypedList(userArrayList, User.CREATOR); It looks like this: And example of the second model:
public class User implements Parcelable {
long id;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm ZZZZ")
Date time;
String image_src;
String first_name;
String last_name;
public User() {
}
public String getFirst_name() {
return first_name;
}
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public String getLast_name() {
return last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
public String getImage_src() {
return image_src;
}
public void setImage_src(String image_src) {
this.image_src = image_src;
}
protected User(Parcel parcel) {
id = parcel.readLong();
time = new Date(parcel.readLong());
image_src = parcel.readString();
first_name = parcel.readString();
last_name = parcel.readString();
}
public static final Creator<User> CREATOR = new Creator<User>() {
#Override
public User createFromParcel(Parcel in) {
return new User(in);
}
#Override
public User[] newArray(int size) {
return new User[size];
}
};
public static Creator<User> getCREATOR() {
return CREATOR;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeLong(id);
// parcel.writeLong(time.getTime());
parcel.writeString(image_src);
parcel.writeString(first_name);
parcel.writeString(last_name);
}
}
Can you help me to find my mistake?
You must initialized userArrayList before use it:
userArrayList = new ArrayList<User>();
in.readTypedList(userArrayList, User.CREATOR);
Initialize ArraList and retrieve the data to this list from parcelable.
Something like this:
userArrayList = new ArrayList<User>();
in.readTypedList(userArrayList, User.CREATOR);
I am developing and spring application and for object mapping I am using ModelMapper library.
I am able to map basic class mapping but when I am trying to map 2 collection elements, source is set of enumeration with additional property like name and description and destination is pojo having id, name and description.
I have tried typemap and converters in mapping profile but I am getting exception of mapper.
And the source class is from other application(whose dependency have been added in pom.xml). I also don't want source type as an argument in setter of destination.
Ex.
SOURCE:
public class VType{
private int id;
private String name;
private String description;
}
public class VDTO{
private Set<VType> vTypes;
public Set<VType> getVTypes(){
return this.vTypes;
}
public void setVType() { //here I don't want to pass source type as an argument
//code stuff that I don't know what to do here
}
}
SOURCE ENUM:
public enum SourceVType{
V1(1, "Name1", "Desc1");
V2(2, "Name2", "Desc2");
private Integer id;
private String name;
private String description;
SourceVType(Integer id, String name, String description) {
this.id = id;
this.name = name;
this.description = description;
}
//getter-setter
}
Have you tried converter feature of modelmapper. You can use typemap converter to achieve this requirement.
#RunWith(JUnit4.class)
public class TempTest {
#Test
public void TestThis(){
final ModelMapper mapper = new ModelMapper();
mapper.addMappings(new PropertyMap<SrcClass, DestClass>() {
#Override
protected void configure() {
this.map().setId(this.source.getId());
this.map().setName(this.source.getName());
mapper.createTypeMap(TypeEnum.class, TypeClass.class).setConverter(
new Converter<TypeEnum, TypeClass>() {
#Override
public TypeClass convert(MappingContext<TypeEnum, TypeClass> mappingContext) {
if (mappingContext.getSource() == null) {
return null;
}
TypeEnum typeEnum = mappingContext.getSource();
TypeClass typeClass = new TypeClass();
typeClass.setId(typeEnum.getId());
typeClass.setName(typeEnum.getName());
return typeClass;
}
});
}
});
SrcClass srcObj = new SrcClass();
srcObj.setId(1);
srcObj.setName("name");
srcObj.setTypes(new HashSet<>(Arrays.asList(TypeEnum.TYPE1, TypeEnum.TYPE2)));
DestClass dstObj = mapper.map(srcObj, DestClass.class);
Assert.assertEquals(srcObj.getId(), dstObj.getId());
Assert.assertEquals(srcObj.getName(), dstObj.getName());
Assert.assertEquals(srcObj.getTypes().size(), dstObj.getTypes().size());
for(TypeClass c : dstObj.getTypes()) {
TypeEnum e = TypeEnum.getById(c.getId());
Assert.assertNotNull(e);
Assert.assertTrue(srcObj.getTypes().contains(e));
}
}
public static <Source, Result> Set<Result> convertAll(Set<Source> source, Function<Source, Result> projection)
{
Set<Result> results = new HashSet<>();
if(source == null) return results;
for (Source element : source)
{
results.add(projection.apply(element));
}
return results;
}
public static class SrcClass{
private Integer id;
private String name;
private Set<TypeEnum> types;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<TypeEnum> getTypes() {
return types;
}
public void setTypes(Set<TypeEnum> types) {
this.types = types;
}
}
public static class DestClass{
private Integer id;
private String name;
private Set<TypeClass> types;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<TypeClass> getTypes() {
return types;
}
public void setTypes(Set<TypeClass> types) {
this.types = types;
}
}
public static enum TypeEnum{
TYPE1(1, "Type 1")
, TYPE2(2, "Type 2")
, TYPE3(3, "Type 3")
, TYPE4(4, "Type 4");
private Integer id;
private String name;
TypeEnum(Integer id, String name) {
this.id = id;
this.name = name;
}
private static final Map<Integer, TypeEnum> byId = new HashMap<>();
private static final Map<String, TypeEnum> byName = new HashMap<>();
static {
for (TypeEnum e : TypeEnum.values()) {
if (byId.put(e.getId(), e) != null) {
throw new IllegalArgumentException("duplicate id: " + e.getId());
}
if (byName.put(e.getName(), e) != null) {
throw new IllegalArgumentException("duplicate name: " + e.getName());
}
}
}
public Integer getId() {
return this.id;
}
public String getName() { return this.name; }
public static TypeEnum getById(Integer id) {
return byId.get(id);
}
public static TypeEnum getByName(String name) {
return byName.get(name);
}
}
public static class TypeClass{
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}