XML incorrect response Spring REST and hibernate

Multi tool use
XML incorrect response Spring REST and hibernate
I have Spring REST and hibernate in my project. I want to display the response in xml format but irrespective of the id I pass in the URL I am getting the incorrect xml response as below:
<COUNTRY id="0">
<population>0</population>
</COUNTRY>
The URL that I hit is :
http://localhost:8080/SpringRestHibernateExample/getCountry/2
Upon debug I have found that the id is correctly getting passed till the DAO layer and also the correct country is getting fetched. Somehow the rendering is not happening correctly.
Here are my classes
Controller
@RequestMapping(value = "/getCountry/{id}", method = RequestMethod.GET,
headers = "Accept=application/xml",
produces="application/xml")
public Country getCountryById(@PathVariable int id) {
return countryService.getCountry(id);
}
Model
@XmlRootElement (name = "COUNTRY")
@XmlAccessorType(XmlAccessType.FIELD)
@Entity
@Table(name="COUNTRY")
public class Country{
@XmlAttribute
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
int id;
@XmlElement
@Column(name="countryName")
String countryName;
@XmlElement
@Column(name="population")
long population;
public Country() {
super();
}
Service
@Transactional
public Country getCountry(int id) {
System.out.println("service"+id);
return countryDao.getCountry(id);
}
DAO
public Country getCountry(int id) {
System.out.println("dao"+id);
Session session = this.sessionFactory.getCurrentSession();
Country country = (Country) session.load(Country.class, new Integer(id));
return country;
}
Can someone please help...
EDIT : replacing load with get solved the issue. But now for /getAllCountries I am receiving the below error:
The resource identified by this request is only capable of generating
responses with characteristics not acceptable according to the request
"accept" headers.
Below is the controller
@RequestMapping(value = "/getAllCountries", method =
RequestMethod.GET,produces="application/xml",
headers = "Accept=application/xml")
public List<Country> getCountries() throws CustomerNotFoundException{
List<Country> listOfCountries = countryService.getAllCountries();
return listOfCountries;
}
load
get
new Integer
id
new Integer
@M.Deinum it worked with get().. can you please tell me why it didnt with load()?
– ghostrider
Jul 3 at 6:28
load
creates a proxy of the actual object without actually going to the database, get
will actually retrieve the object from the database. load
would work if the ongoing transaction was still active, however as you are outside of the service method this isn't the case and the proxy doesn't have the ability to obtain the actual data from the database.– M. Deinum
Jul 3 at 6:29
load
get
load
@M.Deinum Yes even I had a doubt with using load(). I have a different error with /getAllCountries now. Can you please help me with that? I have updated the question
– ghostrider
Jul 3 at 6:34
That is a totally different question, don't ask 2 questions in a single question.
– M. Deinum
Jul 3 at 6:36
2 Answers
2
The problem is your DAO method it uses Session.load
instead of Session.get
.
Session.load
Session.get
The difference between load
and get
is that load
(generally always) returns a lazy proxy. It will only obtain the actual underlying data when data is actually requested (which could also lead to very late EntityNotFoundException
s due to delayed checking in the database). Now generally you wouldn't notice any of the lazy stuff (maybe in performance) but in this case you do. you are outside of an active transaction (and thus Session
) and due to that the proxy cannot obtain the needed data from the database anymore (and because there isn't anything you will get 0
as that is the default for an int
).
load
get
load
EntityNotFoundException
Session
0
int
I recommend to add to the @PathVariable the name of the parameter
Example @PathVariable("id")
Also if you are using an object as ID, you can like an integer use it in all the layer instead the int.
Also, the Integer could be null if is not desired, put in the PathVariable the attribute required = true. if null is not allowed
Finally if you are no planning to operate with the object and return it directly use session.get instead of session.load
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Don't use
load
. useget
. Also don't usenew Integer
just use theid
directly (creating anew Integer
adds overhead).– M. Deinum
Jul 3 at 6:04