javax.servlet.ServletException: Unable to locate object to be marshalled in model - spring

I've looked around bit but can't figure out what am I missing trying to get xml view of result.
Following is the exception I am getting:
javax.servlet.ServletException: Unable to locate object to be marshalled in model: {movies=[com.wickedlynotsmart.imdb.model.Movie#1450f1f, com.wickedlynotsmart.imdb.model.Movie#ac622a, com.wickedlynotsmart.imdb.model.Movie#160c21a, com.wickedlynotsmart.imdb.model.Movie#1677737, com.wickedlynotsmart.imdb.model.Movie#1c3dc66]}
at org.springframework.web.servlet.view.xml.MarshallingView.renderMergedOutputModel(MarshallingView.java:100)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
...
...
Following are the files included in handling the request:
servlet application context file
<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.wickedlynotsmart.imdb.model.Movie</value>
</list>
</property>
</bean>
<bean id="movies" class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg ref="jaxbMarshaller" />
</bean>
domain object
#Entity
#XmlRootElement
public class Movie implements Serializable {
public Movie() {}
//interesting stuff
}
controller
#RequestMapping("/movies")
public class MoviesController {
private static final Log logger = LogFactory.getLog(MoviesController.class);
#Autowired
private MovieManagementService movieManagementService;
#RequestMapping(method=RequestMethod.GET)
public String findAllMovies(Model model) {
List<Movie> movies = movieManagementService.getAllMovies();
model.addAttribute("movies", movies);
return "movies";
}
//interesting stuff
}
Could someone help me out with what I might be missing here?
Thanks.
EDIT: I am basically trying to see BeanNameViewResolver in action for which I already have BeanNameViewResolver configured in the configuration file as following:
<bean id="beanNameViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="2" />
</bean>

Following changes got things working:
wrapper for Movie class to keep JAXB happy
#XmlRootElement(name="movies")
public class MovieList {
private List<Movie> movieList;
public MovieList() {}
public MovieList(List<Movie> movieList) {
this.movieList = movieList;
}
#XmlElement(name="movie")
public List<Movie> getMovieList() {
return movieList;
}
public void setMovieList(List<Movie> movieList) {
this.movieList = movieList;
}
}
controller
#RequestMapping(method=RequestMethod.GET)
public String findAllMovies(Model model) throws MovieNotFoundException {
List<Movie> movieList = movieManagementService.getAllMovies();
MovieList movies = new MovieList(movieList);
model.addAttribute("movies", movies);
return "movies";
}
sevlet application context
<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.wickedlynotsmart.imdb.model.Movie</value>
<value>com.wickedlynotsmart.imdb.model.MovieList</value>
</list>
</property>
</bean>

Related

Why is my #Autowired field null here?

This is not a duplicate of this question. So please don't close it for "is duplicate of" reasons..
I am trying to autowire a private field in my service class using this tutorial. My problem is that restaurantOwnerRepository remains null and does not get initialized.
servlet-context.xml
<context:component-scan base-package="com.mahlzeit.web.server" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="restaurantOwnerRepository" class="com.mahlzeit.web.server.dao.RestaurantOwnerRepository">
<constructor-arg>
<ref bean="sessionFactory" />
</constructor-arg>
</bean>
Service code:
#Component
public class RestaurantInformationServiceImpl extends XsrfProtectedServiceServlet implements RestaurantInformationService {
private static final long serialVersionUID = -4088840947018614411L;
#Autowired
private RestaurantOwnerRepository restaurantOwnerRepository;
private final static Logger logger = Logger.getLogger(RestaurantInformationServiceImpl.class);
#Override
public List<RestaurantDTO> getAvailableRestaurants() {
// restaurantOwnerRepository is 'null'
List<Restaurant> availableRestaurants = restaurantOwnerRepository.getAvailableRestaurants(getSessionId());
return null;
}
private String getSessionId() {
HttpServletRequest httpRequest = getThreadLocalRequest();
return httpRequest.getSession().getId();
}
}
RestaurantOwnerRepository.java
public class RestaurantOwnerRepository implements RestauranOwnerDAO {
private SessionFactory sessionFactory;
public RestaurantOwnerRepository(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
// ..
}
What could be the reason for this?
here is a sample controller for your example , you should define the bean in your context.xml or if you place it in this package : com.mahlzeit.web.server it will be managed by spring automatically , cause as i see you have placed the context:component-scan
#Controller
public class RestaurantInformationServiceImpl {
#Autowired
private RestaurantOwnerRepository restaurantOwnerRepository;
#RequestMapping(value="/")
public #ResponseBody ModelAndView getRestaurants(
HttpServletRequest request,
HttpServletResponse response) {
ModelAndView model = new ModelAndView("yourPage");
List<?> rests = restaurantOwnerRepository.getAvailableRestaurants(httpRequest.getSession().getId());
model.addObject("restList", rests );
return model;
}
}

Getting the entity manager

i'm using spring data jpa but i want execute some costume query so how can i get the entity manager in my java classes to make entityManager.createQuery(..)
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="persistenceYous" />
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="persistence" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
</bean>
You can obtain your EntityManager as in any other spring application:
public class ProductDaoImpl implements ProductDao {
private EntityManager em;
#PersistenceContext
public void setEntityManager(EntityManager em) {
this.em = em;
}
public Collection loadProductsByCategory(String category) {
em. ....
....
}
}
See: http://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-framework-reference/html/orm.html#orm-jpa-straight
In your applicationContext.xml, check that you have the following:
<context:annotation-config />
That will add support for several annotations, such as #PersistenceContext, that injects an EntityManager. So in your Spring-managed beans, you can do:
public class MyClass {
private EntityManager entityManager;
#PersistenceContext
public void setEntityManager(EntityManager em) {
this.entityManager = em
}
public void myMethod() {
Query q = entityManager.createQuery(...);
// ...
}
}
If you want to add suport for just #PersistenceContext, and not the other annotations that <context:annotation-config /> supports, you would delete that from the applicationContext.xml and add the specific BeanPostProcessor:
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" scope="singleton">
<!-- Optional configuration of PersistenceAnnotationBeanPostProcessor, for advanced use cases -->
</bean>
Firstly follow this link to get the steps required to implement..
check this link
In second step he uses #Autowired private JdbcOperations operations;
But that doesn't work for me, so i used the following code.. Which worked for me.
#Component
public class MayorRepositoryImpl extends JdbcDaoSupport implements MayorRepositoryCustom {
#Override
public List<Employee> getUsers(String role) {
return getJdbcTemplate().query("Write your custom query",new RowMapper<Employee>(){
#Override
public Employee mapRow(ResultSet rs, int rownumber) throws SQLException {
// Mapping each row and adding to list and returning the list
Employee employeeBean=new Employee();
employeeBean.setId(rs.getInt("id"));
employeeBean.setEmployeeNumber(rs.getString("employeeNumber"));
employeeBean.setName(rs.getString("name"));
employeeBean.setWorkEmailAddress(rs.getString("workEmailAddress"));
employeeBean.setPersonalEmailAddress(rs.getString("personalEmailAddress"));
return employeeBean;
}
});
}
}
This is perfectly working for me..
If you find any difficulty let me know to help you.
Cheers

JPA - Entities are not stored in database

I am facing a problem, when I tried to insert a data into Database through JPA (#persistanceContex)
Observations
Not getting any errors;
Record is not storing into database (save)
When I tried with listAll() ; it retrieving the data from database
Domain
#Entity
public class Test {
#Id
private int id;
#Column(name="full_name")
private String fullName;
#Column(name="mobile_number")
private int mobileNumber;
.....
}
DAO Class
#Repository("testDAO")
#Transactional
public class TestDAO {
private EntityManager entityManager;
#PersistenceContext(unitName="CRUD_Test_Annotation")
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
public void save(Test test){
entityManager.persist(test);
}
}
Service
#Service("testService")
#Transactional
public class TestService {
private static final Logger logger = LoggerFactory.getLogger(TestService.class);
#Autowired(required=true)
private TestDAO testDAO;
public void save(Test test){
logger.info("TestService::save()");
testDAO.save(test);
}
public void list(){
testDAO.getAll();
}
}
Controller
#RequestMapping(value = "/add", method = RequestMethod.GET)
public String add(Locale locale, Model model) {
Test test = new Test();
test.setId(xx);
test.setFullName("xxxxx");
test.setMobileNumber(yyyyyy);
testService.save(test);
return "home";
}
application-context.xml
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Declare a JPA entityManagerFactory-->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"></property>
<property name="persistenceUnitName" value="CRUD_Test_Annotation" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
</bean>
</property>
</bean>
<!-- Declare a transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
First of all, you don't need two transaction boundaries, I suggest you remove #Transactional from your DAO and keep the one in your service.
Start by verifying that spring-transaction has initiated a transaction: Use the debugger and stop the application after the transaction boundary, for instance in your TestService.save-method. If transactions are running, you will see org.springframework.transaction.interceptor.TransactionInterceptor#invoke in the call stack. If you don't see the TransactionInterceptor, then that's your problem. Post your persistence.xml file if transactions are running.

CustomPropertyEditor is not working

I am new to Spring. I am trying implementing CustomPropertyEditor using PropertyEditorSupport and registering the CustomPropertyEditor in app-context.xml.
Please find the code below.
public class NamePropertyEditor extends PropertyEditorSupport{
#Override
public void setAsText(String text) throws IllegalArgumentException {
//String[] name = text.split(":");
System.out.println("text: "+ text);
Name result = new Name(text, "randomString");
setValue(result);
}
}
app-context file
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="com.property.bean.Name">
<bean class="com.property.editor.NamePropertyEditor"/>
</entry>
</map>
</property>
</bean>
<bean id="exampleBean" class="com.start.CustomEditorExample">
<property name="name">
<value>Varun Bhatia</value></property>
</bean>
Class trying to use PropertyEditor
public static void main(String[] args) {
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.load("classpath:/META-INF/spring/app-context.xml");
//ctx.refresh();
CustomEditorExample bean = (CustomEditorExample) ctx.getBean("exampleBean");
System.out.println(bean.getName());
}
public Name getName() {
System.out.println("getName");
return name;
}
public void setName(Name name) {
System.out.println("setName");
this.name = name;
}
Problem is control is not going to setAsText method.
Code that you have written in main() will not invoke your property editor
Try something like
CustomEditorExample bean = (CustomEditorExample) ctx.getBean("exampleBean");
BeanWrapper wrapper = new BeanWrapperImpl(bean );
wrapper.setPropertyValue("name", "Some Text");//this will invoke your property editor
System.out.println(bean.getName());
I would advise you to read this Spring Docs

Create spring beans, based on a comma-separated list of classes

Is there a way in Spring to create a collection, or array, of beans, based on a comma-separated list of classes. For example:
package mypackage;
public class Bla {
private Set<MyBean> beans;
public void setBeans(Set<MyBean> beans) {
this.beans = beans;
}
}
With the application context:
<bean id="bla" class="mypackage.Bla">
<property name="beans">
<set>
<bean class="mypackage.Bean1, mypackage.Bean2" />
</set>
</property>
</bean>
Preferably the beans are all initialized and wired from the context, leaving the code as simplistic as possible, is this possible?
Use a combination of ApplicationContextAware and ApplicationListener:
public class BeanInitializer implements ApplicationContextAware, ApplicationListener<ContextRefreshedEvent> {
private ApplicationContext context;
private List<Class<?>> beanClasses;
public void onApplicationEvent(final ContextRefreshedEvent event) {
final AutowireCapableBeanFactory beanFactory = this.context.getAutowireCapableBeanFactory();
for (final Class<?> beanClass : this.beanClasses) {
beanFactory.autowire(beanClass, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
}
}
public void setApplicationContext(final ApplicationContext context) throws BeansException {
this.context = context;
}
public void setBeanClasses(final List<Class<?>> beanClasses) {
this.beanClasses = beanClasses;
}
}
in your spring config, do this:
<bean class="com.yourcompany.BeanInitializer">
<property name="beanClasses">
<list>
<value>com.yourcompany.Type1</value>
<value>com.yourcompany.Type2</value>
<value>com.yourcompany.Type3</value>
</list>
</property>
</bean>
Edited: Actually, if you want comma separated, it will probably be more like this:
<bean class="com.yourcompany.BeanInitializer">
<property name="beanClasses"
value="com.yourcompany.Type1,com.yourcompany.Type2,com.yourcompany.Type3" />
</bean>
I don't know if there is a built-in property editor that converts a comma delimited string to a list of classes but if not you can either create one yourself or change your setter method to accept a string and parse the string yourself

Resources