So I have a Spring Boot main() that queries an API that returns some XML (CRed and indented for your viewing pleasure)
<ns1:Entities xmlns:ns1="https://my.company.com/rest/model">
<ns1:Entity name="Model" href="..512971">
<ns1:Attribute name="id" type="Number" value="512971"/>
<ns1:Attribute name="modelNumber" type="String" value="4857395960"/>
</ns1:Entity>
</ns1:Entities>
that I want to deserialize into instances of class Model
public class Model implements java.io.Serializable {
private static final long serialVersionUID = -1234L;
#Id
#Column(name="id")
private Long id;
#Column(name="model_number")
private String modelNumber;
//constructors
public Model() {}
public Model( Long id, String num) {
this.id = id;
this.modelNumber = num;
}
public Model( String idStr, String num) {
this.id = Long.getLong(idStr);
this.modelNumber = num;
}
//getters and setters
public Long getId() {
return id;
}
public void setId( Long id) {
this.id = id;
}
public void setId( String idStr) {
this.id = Long.getLong(idStr);
}
....
}
and
#JsonIgnoreProperties(ignoreUnknown=true)
#JacksonXmlRootElement(localName="Attribute", namespace="ns1")
public class Attribute implements java.io.Serializable {
private static final long serialVersionUID = -5678L;
public String name;
public String type;
public String value;
//constructors
public Entity() {}
public Entity( String name, String type, String value) {
this.name = name;
this.type = type;
this.value = value;
}
//getters and setters
.....
}
and
#JsonIgnoreProperties(ignoreUnknown=true)
#JacksonXmlRootElement(localName="Entity", namespace="ns1")
public class Entity implements java.io.Serializable {
private static final long serialVersionUID = -9876L;
public String name;
public String href;
#JacksonXmlProperty(localName="Attribute")
#JacksonXmlElementWrapper(useWrapping=false)
private List<Attribute> list_attribute = new LinkedList<Attribute>();
//constructors
public Entity() {}
public Entity( String name, String href, List<Attribute> lisst) {
this.name = name;
this.href = href;
this.list_attribute = lisst;
}
//getters and setters
....
}
and
#JsonIgnoreProperties(ignoreUnknown=true)
#JacksonXmlRootElement(localName="Entities", namespace="ns1")
public class Entities implements java.io.Serializable {
private static final long serialVersionUID = -2345L;
#JacksonXmlProperty(localName="Entity")
#JacksonXmlElementWrapper(useWrapping=false)
private List<Entity> list_entity = new LinkedList<Entity>();
//constructors
public Entities() {}
public Entities( List<Entity> lisst) {
this.list_entity = lisst;
}
//getters and setters
public List<Entity> getList_entity() {
return list_entity;
}
public void setList_entity( List<Entity> lisst) {
this.list_entity = lisst;
}
....
}
So at last we get to a chunk of main()
HttpHeaders headers = new HttpHeaders();
headers.add( HttpHeaders.ACCEPT, MediaType.APPLICATION_XML_VALUE);
HttpEntity<Object> reqquest = new HttpEntity<Object>( null, headers);
ResponseEntity<String> responnse = this.restTemplate.exchange( "https://myendpointgoeshere.com", HttpMethod.GET, reqquest, String.class, 0);
Entities entities_obj = this.xmlMapper.readValue( xmlStr, Entities.class);
List<Model> list_model = Model.deserialize( entities_obj); // <--
throws
IAE - fld:id - type: + Number - value:512971
java.lang.IllegalArgumentException: Can not set java.lang.Long field ...Model.id to null
and yet
Model model_0 = list_model.get[0];
System.out.println( model_0);
does show a correctly populated instance of Model. So this is all mostly right but not 100% right. What am I doing wrong/not doing right? And there will be many kinds of Entity, Model being only one so Model should extend Entity ?
TIA,
Still-learning Steve
Related
I am using #Mapping to map my entity class to DTO class.All values are being mapped perfectly except one- hostPlayerId is coming null.
I am hitting my API below which is returning Lobby object and I am using MapStruct to map the Entity to the DTO. Its mapping every field except hostPlayerId field.
#GetMapping("/lobby/{id}")
#ResponseStatus(HttpStatus.OK)
#ResponseBody
public LobbyGetDTO getLobbyInfo(#RequestHeader("X-Auth-Token") String token, #PathVariable("id") long id) {
Lobby lobby = lobbyService.getLobby(id);
log.info("here here "+lobby.toString());
LobbyGetDTO lobbyInfoDTO = DTOMapper.INSTANCE.convertEntityToLobbyGetDTO(lobby);
log.info(lobbyInfoDTO.toString());
return lobbyInfoDTO;
}
The logger after hitting the API -
2020-04-18 00:00:01.738 INFO 18486 --- [nio-8080-exec-6] c.u.i.s.s.controller.LobbyController : here here Lobby{id=2, name='Test Lobby', hostPlayerId=1, playerIds=[], chatId=null, gameId=null, status=0}
2020-04-18 00:00:01.740 INFO 18486 --- [nio-8080-exec-6] c.u.i.s.s.controller.LobbyController : LobbyGetDTO{id=2, name='Test Lobby', hostPlayerId=null, playerIds=[], gameId=null}
Map Interface-
#Mapper
public interface DTOMapper {
DTOMapper INSTANCE = Mappers.getMapper(DTOMapper.class);
#Mapping(source = "id", target = "id")
#Mapping(source = "name", target = "name")
#Mapping(source = "gameId", target = "gameId")
#Mapping(source = "hostPlayerId", target = "hostPlayerId")
#Mapping(source = "playerIds", target = "playerIds")
LobbyGetDTO convertEntityToLobbyGetDTO(Lobby lobby);
}
mapping implementation method created during build phase-
#Override
public LobbyGetDTO convertEntityToLobbyGetDTO(Lobby lobby) {
if ( lobby == null ) {
return null;
}
LobbyGetDTO lobbyGetDTO = new LobbyGetDTO();
lobbyGetDTO.setGameId( lobby.getGameId() );
lobbyGetDTO.setName( lobby.getName() );
lobbyGetDTO.setId( lobby.getId() );
List<Long> list = lobby.getPlayerIds();
if ( list != null ) {
lobbyGetDTO.setPlayerIds( new ArrayList<Long>( list ) );
}
lobbyGetDTO.sethostPlayerId( lobby.gethostPlayerId() );
return lobbyGetDTO;
}
My DTO class
public class LobbyGetDTO {
private Long id;
private String name;
private Long hostPlayerId;
private List<Long> playerIds;
private Long gameId;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long gethostPlayerId() {
return hostPlayerId;
}
public void sethostPlayerId(Long hostPlayerIdPlayerId) {
this.hostPlayerId = hostPlayerId;
}
public List<Long> getPlayerIds() {
return playerIds;
}
public void setPlayerIds(List<Long> playerIds) {
this.playerIds = playerIds;
}
public Long getGameId() {
return gameId;
}
public void setGameId(Long gameId) {
this.gameId = gameId;
}
}
My Entity class
#Entity
#Table(name = "LOBBY")
public class Lobby implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private Long id;
#Column(nullable = false)
private String name;
#Column(nullable = false)
private Long hostPlayerId;
}
I am unable to understand what am I missing here.
Maybe, getter and setter in the DTO need to be named as getHostPlayerId() / setHostPlayerId() so that the mapper could detect them.
Also, you do not assign any value in the setter because of typo in the argument:
public void sethostPlayerId(Long hostPlayerIdPlayerId) {
this.hostPlayerId = hostPlayerId;
}
should be:
public void setHostPlayerId(Long hostPlayerId) {
this.hostPlayerId = hostPlayerId;
}
I am new with using spring boot + jersey api + JPA.
I hava three entity that uses one to many bidirectional mapping. When i used spring boot + jersey api+ JPA I get error :
failed to lazily initialize a collection of role: com.kavinaam.GSTbilling.entity.Country.states, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.kavinaam.GSTbilling.entity.City["states"]->com.kavinaam.GSTbilling.entity.States["countyId"]->com.kavinaam.GSTbilling.entity.Country["states"])
I have added my entity, dao , services and end point.
#Entity
#Table(name="country")
public class Country implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id")
private int id;
#Column(name="countryName")
private String countryName;
#OneToMany(mappedBy = "countyId",cascade = CascadeType.ALL)
private Set<States> states;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public Set<States> getStates() {
return states;
}
public void setStates(Set<States> states) {
this.states = states;
}
}
My state class:
#Entity
#Table(name="states")
public class States implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id")
private int id;
#ManyToOne
#JoinColumn(name="countyId")
private Country countyId;
#Column(name="stateName")
private String stateName;
#OneToMany(mappedBy = "states", cascade = CascadeType.ALL)
private Set<City> city;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Country getCountyId() {
return countyId;
}
public void setCountyId(Country countyId) {
this.countyId = countyId;
}
public String getStateName() {
return stateName;
}
public void setStateName(String stateName) {
this.stateName = stateName;
}
public Set<City> getCity() {
return city;
}
public void setCity(Set<City> city) {
this.city = city;
}
}
My city class:
#Entity
#Table(name="cities")
public class City implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id")
private int id;
#ManyToOne
#JoinColumn(name="stateId")
private States states;
#Column(name="cityName")
private String cityName;
#Column(name="zip")
private String zip;
public void setId(int id) {
this.id = id;
}
public void setZip(String zip) {
this.zip = zip;
}
public States getStates() {
return states;
}
public void setStates(States states) {
this.states = states;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public String getZip() {
return zip;
}
public int getId() {
return id;
}
}
My DAO:
#Transactional
#Repository
public class GSTCityDAO implements IGSTCityDAO {
#PersistenceContext
private EntityManager entityManager;
//#SuppressWarnings("unchecked")
#Override
public List<City> getAllCities() {
//Session session = sessionFactory.getCurrentSession();
String hql = "FROM City as ct ORDER BY ct.id";
List<City> l = entityManager.createQuery(hql,City.class).getResultList();
return l;
}
#Override
public City getCityById(int cityId) {
return entityManager.find(City.class, cityId);
}
#SuppressWarnings("unchecked")
#Override
public List<City> getCityByStateId(States stateId) {
String getcitybystate = " FROM City as c WHERE c.states = ?";
return (List<City>) entityManager.createQuery(getcitybystate).setParameter(1, stateId).getResultList();
}
#Override
public void addCity(City city) {
entityManager.persist(city);
}
#Override
public void updateCity(City city) {
City cityctl = getCityById(city.getId());
cityctl.setCityName(city.getCityName());
cityctl.setZip(city.getZip());
cityctl.setStates(city.getStates());
entityManager.flush();
}
#Override
public void deleteCity(int cityId) {
entityManager.remove(getCityById(cityId));
}
#Override
public boolean cityExists(String name, String zip) {
String hql = "FROM City WHERE cityName = ? and zip = ?";
int count = entityManager.createQuery(hql).setParameter(1,name).setParameter(2, zip).getResultList().size();
return count > 0 ? true : false;
}
}
Services:
#Service
public class GSTCityService implements IGSTCityService {
#Autowired
private IGSTCityDAO cityDAO;
#Override
public List<City> getAllCities() {
List<City> l = cityDAO.getAllCities();
Hibernate.initialize(l);
return l;
}
public List<City> getCityByStateId(States stateId) {
return cityDAO.getCityByStateId(stateId);
}
#Override
public City getCityById(int cityId) {
City city = cityDAO.getCityById(cityId);
return city;
}
#Override
public synchronized boolean addCity(City city) {
if(cityDAO.cityExists(city.getCityName(), city.getZip())){
return false;
}else{
cityDAO.addCity(city);
return true;
}
}
#Override
public void updateCity(City city) {
cityDAO.updateCity(city);
}
#Override
public void deleteCity(int cityId) {
cityDAO.deleteCity(cityId);
}
}
End Point:
#Component
#Path("/")
public class Test {
private static final Logger logger = LoggerFactory.getLogger(Test.class);
#Autowired
private IGSTCityService cityService;
#GET
#Path("/hi")
#Produces(MediaType.APPLICATION_JSON)
public Response hello(){
return Response.ok("Hello GST").build();
}
#GET
#Path("/test")
#Produces(MediaType.APPLICATION_JSON)
public Response getAllDate(){
List<City> list = cityService.getAllCities();
for(City city: list){
System.out.println(city);
}
return Response.ok(list).build();
}
#GET
#Path("/test/{id}")
#Produces(MediaType.APPLICATION_JSON)
public Response getAllDateBySome(#PathParam("id") Integer id){
States state = new States();
state.setId(id);
List<City> list = cityService.getCityByStateId(state);
return Response.ok(list).build();
}
#GET
#Path("/{id}")
#Produces(MediaType.APPLICATION_JSON)
public Response getDataById(#PathParam("id")Integer id){
City citl = cityService.getCityById(id);
return Response.ok(citl).build();
}
#POST
#Path("/add")
#Consumes(MediaType.APPLICATION_JSON)
public Response addData(City city){
boolean isAdded = cityService.addCity(city);
if(!isAdded){
return Response.status(Status.CONFLICT).build();
}
return Response.created(URI.create("/gst/"+ city.getId())).build();
}
#PUT
#Path("/update")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response updateCountry(City city){
cityService.updateCity(city);
return Response.ok(city).build();
}
#DELETE
#Path("/{id}")
#Consumes(MediaType.APPLICATION_JSON)
public Response deleteCountry(#PathParam("id")Integer id){
cityService.deleteCity(id);
return Response.noContent().build();
}
}
I am using import org.springframework.transaction.annotation.Transactional; for transnational in DAO. Also I can not use #PersistenceContext(type=PersistenceContextType.EXTENDED) and fetch type Eager because I get error of Maximum stack size exceeded
I solved it by using the #JsonBackReference on OneToMany relationship. The problem is with the Serialization and Deserialization.
" the property annotated with #JsonManagedReference annotation is handled normally (serialized normally, no special handling for deserialization) and the property annotated with #JsonBackReference annotation is not serialized; and during deserialization, its value is set to instance that has the "managed" (forward) link."
You should do one or both of the following:
1) Move the #Transactional from DAO to Service. Thats a good idea in general as usually are still processing the result entities in some way on that layer.
2) Fetch the dependencies in the queries explicitly:
select ct FROM City as ct inner join fetch ct.states s ORDER BY ct.id
I use realm to parse this JSON, but I get this error:
java.lang.IllegalArgumentException: JSON object doesn't have the primary key field 'id'.
LINK of Json
this is my method :
Realm r = Realm.getDefaultInstance();
r.beginTransaction();
r.createOrUpdateObjectFromJson(Application.class,result);
r.commitTransaction();
my Application class is :
public class Application extends RealmObject {
#PrimaryKey
private int id;
private RealmList<girl> girls;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public RealmList<girl> getGirls() {
return girls;
}
public void setGirls(RealmList<girl> girls) {
this.girls = girls;
}
public Application() {
}
public Application(int id, RealmList<girl> girls) {
this.id = id;
this.girls = girls;
}
}
my class girl is
public class girl extends RealmObject {
#PrimaryKey
private int id;
private String name;
private String ville;
private String tel;
private String photo;
//getters and setters and constructors with and without params
}
try to use realm.copyFromRealm(); and for more refer bellow link
https://github.com/realm/realm-java/issues/1973
I have a hibernate entity class
public class MyComplexClass implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
String name;
int number;
#ElementCollection
Map<String,String> myMap;
#ManyToOne
Simple simple;
public MyComplexClass(String name, int number, Map<String,String> myMap) {
this.name = name;
this.port = number;
this.myMap = myMap;
}
public MyComplexClass() {
// TODO Auto-generated constructor stub
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setNumber(int number) {
this.port = number;
}
public int getPort() {
return port;
}
public void setMyMap(Map<String,String> myMap) {
this.myMap = myMap;
}
public Map<String,String> getMyMap() {
return this.myMap;
}
public Simple getSimple() {
return this.simple;
}
And in the class simple I have a mapping of the form
#Entity
#Table(name = "Simple")
public class Simple implements Comparable<Simple>, Serializable {
#JsonProperty
#OneToMany(mappedBy="simple",fetch = FetchType.EAGER,cascade = CascadeType.ALL)
List<MyComplexClass> myComplexClass;
public void setMyComplexClass(List<MyComplexClass> myComplexClass) {
this.myComplexClass = myComplexClass;
}
public List<MyComplexClass> getMyComplexClass() {
return this.myComplexClass;
}
Somewhere in the system I set the values as
Map<String, String> myMap = new HashMap<String,String>();
myMap.put("value","value");
MyComplexClass myComplexClass = new MyComplexclass("a", 123, myMap)
List<MyComplexClass> myComplexClassList = new ArrayList<MyComplexClass>();
myComplexClassList.add(myComplexClassList)
simple.setMyComplexClass(myComplexClassList);
// save to the database
dao.save(simple);
But when I get the value as
Simple simple = dao.getSimple(simple.id);
`simple.getMyComplexClass.get(0).getMyMap.get("value")`
. It returns a null pointer . When I debug I see that the simple.getMyComplexClass() is null itself
Why isn't it returning the values set? Is it related to the database or in memory cache?
In the database I do see a null in the foreign key column of the MyComplex class table, is this the reason?
my question here is how do i return values selected from hibernate query in the json form.
BankController.java
#RequestMapping(value = "/getohlcall", method = RequestMethod.POST)
public #ResponseBody List<Trading_Data> getOhlcAll(#RequestBody OhlcRequest ohlcRequest) {
List<Trading_Data> list;
list = bankServices.getOhlc(ohlcRequest);
return list;
}
My DAO implementation class which for now returns four values.
BankDaoImpl.java
public List<Trading_Data> getOhlc(OhlcRequest ohlcRequest){
sessionFactory.openSession();
session=sessionFactory.openSession();
Criteria cr = session.createCriteria(Trading_Data.class)
.setProjection(Projections.projectionList()
.add(Projections.property("minPrice"), "minPrice")
.add(Projections.property("maxPrice"), "maxPrice")
.add(Projections.property("closingPrice"), "closingPrice")
.add(Projections.property("prevClosing"), "prevClosing"))
.setResultTransformer(Transformers.aliasToBean(Trading_Data.class));
List<Trading_Data> list = cr.list();
return list;
}
My entity class which is mapped with my table in database.
Trading_Data.java
public class Trading_Data {
#Entity
#Table
#JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Trading_Data {
#Id
#Column
#JsonView(View.Summary.class)
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column
#JsonView(View.Summary.class)
private String stockCode;
#Column
private long maxPrice;
#Column
private long minPrice;
#Column
private long closingPrice;
#Column
private long prevClosing;
#Column
#JsonView(View.Summary.class)
private String eDate;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getStockCode() {
return stockCode;
}
public void setStockCode(String stockCode) {
this.stockCode = stockCode;
}
public long getMaxPrice() {
return maxPrice;
}
public void setMaxPrice(long maxPrice) {
this.maxPrice = maxPrice;
}
public long getMinPrice() {
return minPrice;
}
public void setMinPrice(long minPrice) {
this.minPrice = minPrice;
}
public long getClosingPrice() {
return closingPrice;
}
public void setClosingPrice(long closingPrice) {
this.closingPrice = closingPrice;
}
public long getPrevClosing() {
return prevClosing;
}
public void setPrevClosing(long prevClosing) {
this.prevClosing = prevClosing;
}
public String geteDate() {
return eDate;
}
public void seteDate(String eDate) {
this.eDate = eDate;
}
}
Json data i am currently getting is
[
{
"id": 0,
"maxPrice": 54,
"minPrice": 58,
"closingPrice": 45,
"prevClosing": 215
}
]
as you can see i don't want id for this api but i might want for some other api.
My questions are:-
is there no way for eg. returning only those values(in json format) which are selected by hibernate query ?
for e.g i created one pojo class which has four properties (maxprice, minprice, prevclosing,closingprice). can i map this pojo class with values returned by hibernate query and return to the client in json format?
Try to use 'produces' in your resource method. Like this :
#RequestMapping(value = "/getohlcall", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody List<Trading_Data> getOhlcAll(#RequestBody OhlcRequest ohlcRequest) {
List<Trading_Data> list;
list = bankServices.getOhlc(ohlcRequest);
return list;
}