I just started with Spring Boot Data Neo4j and trying to finish the movie tutorial. I got this ERROR but not really sure how to debug. Error summary : (1) Error creating bean (2)Could not autowire field. Any help, thank you.
My files structure as follows :
SpringBootApplication.java
package com.test.springdataneothree;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.test.services.MovieService;
#EnableAutoConfiguration
#SpringBootApplication
public class SpringdataneothreeApplication implements CommandLineRunner {
#Autowired
MovieService movieService;
public static void main(String[] args) {
SpringApplication.run(SpringdataneothreeApplication.class, args);
}
#Override
public void run(String... arg0) throws Exception {
System.out.println("Main Spring Boot Class");
movieService.countMovie();
}
}
Movie.java
package com.test.movie;
import org.neo4j.ogm.annotation.GraphId;
import org.neo4j.ogm.annotation.NodeEntity;
#NodeEntity(label ="Movie")
public class Movie {
#GraphId
private Long id;
String title;
int released;
String tagline;
public Movie() { }
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getReleased() {
return released;
}
public void setReleased(int released) {
this.released = released;
}
public String getTagline() {
return tagline;
}
public void setTagline(String tagline) {
this.tagline = tagline;
}
}
MovieService.java
package com.test.services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.test.repositories.MovieRepository;
#Service("MovieService")
public class MovieService {
#Autowired
MovieRepository movieRepository;
public void countMovie() {
movieRepository.count();
}
}
MovieRepository.java
package com.test.repositories;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import com.test.movie.Movie;
#Repository
public interface MovieRepository extends GraphRepository<Movie> {
Movie findById(long id);
Movie findByTitle(#Param("title") String title);
#Query("MATCH (m:Movie) WHERE m.title =~ ('(?i).*'+{title}+'.*') RETURN m")
Collection<Movie> findByTitleContaining(#Param("title") String title);
#Query("MATCH (m:Movie)<-[:ACTED_IN]-(a:Person) RETURN m.title as movie, collect(a.name) as cast LIMIT {limit}")
List<Map<String,Object>> graph(#Param("limit") int limit);
}
MyNeo4jConfiguration.java
package com.test.configuration;
import org.neo4j.ogm.session.SessionFactory;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#EnableTransactionManagement
#EnableScheduling
#ComponentScan(basePackages = {"com.test"})
#Configuration
#EnableNeo4jRepositories(basePackages = "com.test.repositories")
public class MyNeo4jConfiguration extends Neo4jConfiguration {
#Override
public SessionFactory getSessionFactory() {
return new SessionFactory("com.test.movie");
}
}
You have a problem with auto wiring: the annotation on the MovieService is wrong, it should be:
#Service("movieService")
or just
#Service
You are trying to inject a bean with the capitalised name, and the context can't find it (the injection is done by name). Another solution is to use the #Qualifier annotation on the auto wired field, like
#Autowired
#Qualifier("MovieService")
MovieService movieService;
Related
I'm self-studying in Spring boot application and encountered this problem. Weird thing is that I only followed the tutorial but still encountered this
Parameter 0 of constructor in com.example.Project1.service.PersonService required a bean of type 'com.example.Project1.dao.PersonDao' that could not be found.
I have one controller, 2 DAO files, 1 Person for model and 1 for service class.
These are my codes:
PersonController:
package com.example.Project1.api;
import com.example.Project1.model.Person;
import com.example.Project1.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RequestMapping("api/v1/person")
#RestController
public class PersonController {
private final PersonService personService;
#Autowired
public PersonController(PersonService personService){
this.personService = personService;
}
#PostMapping
public void addPerson(#RequestBody Person person){
personService.addPerson(person);
}
}
FakePersonDataAccessService
package com.example.Project1.dao;
import com.example.Project1.model.Person;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
#Repository("fakeDao")
public class FakePersonDataAccessService implements PersonDao {
private static List<Person> DB = new ArrayList<>();
#Override
public int insertPerson(UUID id, Person person){
DB.add(new Person(id, person.getName()));
return 1;
}
}
PersonDao
package com.example.Project1.dao;
import com.example.Project1.model.Person;
import java.util.UUID;
public interface PersonDao {
int insertPerson(UUID id, Person person);
default int insertPerson(Person person){
UUID id = UUID.randomUUID();
return insertPerson(id, person);
}
}
Person
package com.example.Project1.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.UUID;
public class Person {
private final UUID id;
private final String name;
public Person(#JsonProperty("id") UUID id, #JsonProperty("name") String name){
this.id = id;
this.name = name;
}
public UUID getId(){
return id;
}
public String getName(){
return name;
}
}
PersonService
package com.example.Project1.service;
import com.example.Project1.dao.PersonDao;
import com.example.Project1.model.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
#Service
public class PersonService {
private final PersonDao personDao;
#Autowired
public PersonService(#Qualifier("mongo") PersonDao personDao){
this.personDao = personDao;
}
public int addPerson(Person person){
return personDao.insertPerson(person);
}
}
I've tried googling the error but found no answer. Hope someone can enlighten me about the error encountered. Thank you~!
You only have "fakeDao" qualifier class that implements PersonDao but your injecting "mongo" qualifier. As another option, you can just removed the #Qualifier annotation in PersonService constructor since you only have one class that implements PersonDao
I am trying to create restful api but my controller is not working and I'm getting the error shown below:
{
"timestamp": "2020-06-11T15:28:18.103+00:00",
"status": 404,
"error": "Not Found",
"message": "",
"path": "/path/findCarsAfterYear/2020"
}
Please help me to resolve this.
Entity Class
package com.example.demo.data;
import javax.persistence.*;
#Entity
public class Car {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column
private long id;
#Column
private String model;
#Column
private Integer year;
// standard getters and setters
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public Integer getYear() {
return year;
}
public void setYear(Integer year) {
this.year = year;
}
}
Repository Class
package com.example.demo.Repository;
import com.example.demo.data.Car;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.query.Procedure;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
#Repository
public interface CarRepository extends JpaRepository<Car, Integer> {
#Query("Select wds from Car wds where year=?1 ")
List<Car> findCarsAfterYear(Integer year);
}
Service class
package com.example.demo.service;
import com.example.demo.Repository.CarRepository;
import com.example.demo.data.Car;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
#Service
public class CarService {
#Autowired
CarRepository carRepository;
public List<Car> findCarsAfterYear(Integer id) {
return carRepository.findCarsAfterYear(id);
}
}
Controller class
package com.example.demo.Controller;
import com.example.demo.data.Car;
import com.example.demo.service.CarService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
#Controller
#RequestMapping(path="/test")
public class CarController {
#Autowired(required=true)
private CarService carService;
#GetMapping(value="/findCarsAfterYear/{id}")
public List<Car> findCarsAfterYear(Integer id) {
return carService.findCarsAfterYear(id);
}
}
Application Class
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#Configuration
#SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
#EnableJpaRepositories("com.example.demo.Repository")
#EntityScan("com.example.demo.data")
#ComponentScan(basePackages="com.example.demo.service,com.example.demo.Controller")
#EnableCaching
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
In you want to use #Controller then you have to provide #ResponseBody explicitly.
#Controller
#RequestMapping(path="/test")
public class CarController {
#Autowired(required=true)
private CarService carService;
#GetMapping(value="/findCarsAfterYear/{id}")
#ResponseBody
public List<Car> findCarsAfterYear(Integer id) {
return carService.findCarsAfterYear(id);
}
}
But in case #RestController, which is combination of #Controllerand #ResponseBody
#RestController
#RequestMapping(path="/test")
public class CarController {
#Autowired(required=true)
private CarService carService;
#GetMapping(value="/findCarsAfterYear/{id}")
public List<Car> findCarsAfterYear(Integer id) {
return carService.findCarsAfterYear(id);
}
}
I hope this will be helpful.
the following error I am getting :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field employeeDAO in com.example.demo.controller.EmployeeController required a bean of type 'com.example.demo.dao.EmployeeDAO' that could not be found.
Action:
Consider defining a bean of type 'com.example.demo.dao.EmployeeDAO' in your configuration.
my folder structure:
below are the files:
1.
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
#EnableJpaRepositories
public class RestCrudDemo1Application {
public static void main(String[] args) {
SpringApplication.run(RestCrudDemo1Application.class, args);
}
}
2.
package com.example.demo.controller;
import java.util.List;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.dao.EmployeeDAO;
import com.example.demo.model.Employee;
#RestController
#RequestMapping("/company")
public class EmployeeController {
#Autowired
EmployeeDAO employeeDAO;
#PostMapping ("/employee")
public Employee createEmployee(#Valid #RequestBody Employee emp){
return employeeDAO.save(emp);
}
#GetMapping ("/findAll")
public List<Employee> findAll(){
return employeeDAO.findAll();
}
#GetMapping("/employees/{id}")
public ResponseEntity<Employee> getEmployeeById(#PathVariable(value = "id") Long empid){
Employee emp = employeeDAO.findOne(empid);
if (emp==null){
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok().body(emp);
}
#PutMapping("/employees/{id}")
public ResponseEntity<Employee> updateEmployee(#PathVariable(value = "id") Long empid, #Valid #RequestBody Employee empDetails){
Employee emp = employeeDAO.findOne(empid);
if (emp==null){
return ResponseEntity.notFound().build();
}
emp.setName(empDetails.getName());
emp.setDesignation(empDetails.getExpertise());
emp.setExpertise(empDetails.getExpertise());
Employee updateEmployee = employeeDAO.save(emp);
return ResponseEntity.ok().body(updateEmployee);
}
#DeleteMapping("/employees/{id}")
public ResponseEntity<Employee> deleteEmployee(#PathVariable(value = "id") Long empid){
Employee emp = employeeDAO.findOne(empid);
if (emp==null){
return ResponseEntity.notFound().build();
}
employeeDAO.delete(emp);
return ResponseEntity.ok().build();
}
}
3.
package com.example.demo.dao;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.example.demo.model.Employee;
import com.example.demo.repository.EmployeeRepository;
public class EmployeeDAO {
#Autowired
EmployeeRepository employeeRepository;
public Employee save(Employee emp){
return employeeRepository.save(emp);
}
public List<Employee> findAll(){
return employeeRepository.findAll();
}
public Employee findOne(Long empid){
return employeeRepository.findOne(empid);
}
public void delete(Employee emp){
employeeRepository.delete(emp);
}
}
4.
package com.example.demo.model;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotBlank;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
#Entity
#Table(name = "Employees")
#EntityListeners(AuditingEntityListener.class)
public class Employee {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long Id;
#NotBlank
private String name;
#NotBlank
private String designation;
#NotBlank
private String expertise;
#NotBlank
#Temporal(TemporalType.TIMESTAMP)
#LastModifiedDate
private Date createdAt;
public long getId() {
return Id;
}
public void setId(long id) {
Id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
public String getExpertise() {
return expertise;
}
public void setExpertise(String expertise) {
this.expertise = expertise;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
}
5.
package com.example.demo.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.demo.model.Employee;
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
public Employee findOne(Long empid);
}
From the error, I get to know that employee dao bean has not been created for autowiring into the controller.
By analysing your employee dao class, you forgot to annotate with #Repository due to which bean has not been created by context scanning.
Annotate empoyeedao class with #Repository. It should solve your problem.
I'm trying to set up a Spring-Data-Rest App using Spring Boot 1.5.9.RELEASE. I have a ConstraintValidator set up like this:
UniqueEmail.java:
import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.ReportAsSingleViolation;
import javax.validation.constraints.NotNull;
import java.lang.annotation.*;
#Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Constraint(validatedBy = {UniqueEmailValidator.class})
#NotNull
#ReportAsSingleViolation
public #interface UniqueEmail {
Class<?>[] groups() default {};
String message() default "{eu.icarus.momca.backend.domain.validation.UniqueEmail.message}";
Class<? extends Payload>[] payload() default {};
#Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
#Retention(RetentionPolicy.RUNTIME)
#Documented
static #interface List {
UniqueEmail[] value();
}
}
UniqueEmailValidator.java:
import eu.icarus.momca.backend.domain.repository.AccountRepository;
import org.springframework.beans.factory.annotation.Autowired;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class UniqueEmailValidator implements ConstraintValidator<UniqueEmail, String> {
#Autowired
private AccountRepository accountRepository;
#Override
public void initialize(UniqueEmail annotation) {
}
#Override
public boolean isValid(String email, ConstraintValidatorContext context) {
return accountRepository.findByEmail(email) == null;
}
}
I've also set up listeners for the beforeCreate and beforeSave repository methods:
RestConfiguration.java:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
#Configuration
public class RestConfiguration extends RepositoryRestConfigurerAdapter {
#Override
public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
validatingListener.addValidator("beforeCreate", localValidatorFactoryBean());
validatingListener.addValidator("beforeSave", localValidatorFactoryBean());
}
#Bean
#Primary
LocalValidatorFactoryBean localValidatorFactoryBean() {
return new LocalValidatorFactoryBean();
}
}
My problem:
The validator seems to work when the repository methods are called through REST endpoints, however I also try to set up some stuff in the connected database via a CommandLineRunner that uses the same repository. When the calls to the repository are validated, the autowired AccountRepository in the ConstraintValidator is null even if it isn't null at the same time in the CommandLineRunner that also has the same repository autowired. I don't understand this.
Does anybody have an idea why the repository is null when the validation is triggered from the CommandLineRunner?
Any help is greatly appreciated.
Daniel
Edit: added the CommandLineRunner Code
InitAdminData.java:
import eu.icarus.momca.backend.domain.entity.Account;
import eu.icarus.momca.backend.domain.entity.AccountDetails;
import eu.icarus.momca.backend.domain.entity.AccountProfile;
import eu.icarus.momca.backend.domain.entity.Client;
import eu.icarus.momca.backend.domain.enumeration.AccountRoles;
import eu.icarus.momca.backend.domain.enumeration.ClientRoles;
import eu.icarus.momca.backend.domain.enumeration.GrantTypes;
import eu.icarus.momca.backend.domain.repository.AccountRepository;
import eu.icarus.momca.backend.domain.repository.ClientRepository;
import eu.icarus.momca.backend.domain.service.AccountService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
#Component
public class InitAdminData implements CommandLineRunner {
private static final Collection<AccountRoles> DEFAULT_ACCOUNT_ROLES = Arrays.asList(AccountRoles.ROLE_ACCOUNT, AccountRoles.ROLE_ADMINISTRATOR, AccountRoles.ROLE_CLIENT_OWNER);
private static final Logger logger = LoggerFactory.getLogger(InitAdminData.class);
private AccountRepository accountRepository;
private AccountService accountService;
#Value("${app.admin-email}")
private String adminEmail;
#Value("${app.admin-name}")
private String adminName;
#Value("${app.admin-password}")
private String adminPassword;
private ClientRepository clientRepository;
#Value("${app.default-client-description}")
private String defaultClientDescription;
#Autowired
public InitAdminData(AccountRepository accountRepository, AccountService accountService, ClientRepository clientRepository) {
this.accountRepository = accountRepository;
this.clientRepository = clientRepository;
this.accountService = accountService;
}
private Account initAdminAccount() {
Account adminAccount = accountRepository.findByAccountProfile_Name(adminName);
if (adminAccount == null) {
adminAccount = new Account();
logger.info("Initialized new admin account");
} else {
logger.info("Refreshed admin account");
}
setAdminAccountData(adminAccount);
return accountService.save(adminAccount, adminPassword);
}
private void initDefaultClient(Account adminAccount) {
long adminAccountId = adminAccount.getId();
Collection<Client> adminClients = clientRepository.findAllByOwnerId(adminAccountId);
if (adminClients.isEmpty()) {
Client defaultClient = new Client();
defaultClient.setOwnerId(adminAccountId);
defaultClient.setDescription(defaultClientDescription);
Collection<ClientRoles> clientRoles = new HashSet<>(2);
clientRoles.add(ClientRoles.ROLE_CLIENT);
clientRoles.add(ClientRoles.ROLE_DEFAULT_CLIENT);
defaultClient.setRoles(clientRoles);
Collection<GrantTypes> grantTypes = new HashSet<>();
grantTypes.add(GrantTypes.authorization_code);
grantTypes.add(GrantTypes.client_credentials);
grantTypes.add(GrantTypes.password);
grantTypes.add(GrantTypes.refresh_token);
defaultClient.setGrantTypes(grantTypes);
defaultClient = clientRepository.save(defaultClient);
logger.info(String.format("Added new default client with id '%s'", defaultClient.getId()));
}
}
#Override
public void run(String... args) {
Account adminAccount = initAdminAccount();
initDefaultClient(adminAccount);
}
private void setAdminAccountData(Account adminAccount) {
adminAccount.setEmail(adminEmail);
adminAccount.setRoles(DEFAULT_ACCOUNT_ROLES);
adminAccount.setAccountDetails(new AccountDetails());
adminAccount.setAccountProfile(new AccountProfile(adminName));
}
}
Add the #ComponentScan annotation.
#ComponentScan
public class InitAdminData implements CommandLineRunner {
...
}
I think you may have few cases :-
you haven't autowired your service and Repo
you haven't scan your Repo where you have your service and Repo.
Or you haven't use #Component(any stereotype) annotation on your classes which you are autowiring
Hy,
Having these three classes I have found a problem:
package xpadro.spring.jms;
import javax.jms.ConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.support.converter.MarshallingMessageConverter;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
#SpringBootApplication
public class JmsJavaconfigApplication {
public static void main(String[] args) {
SpringApplication.run(JmsJavaconfigApplication.class, args);
}
#Bean
public Jaxb2Marshaller jaxb2Marshaller(){
Jaxb2Marshaller jaxb = new Jaxb2Marshaller();
Class array[] = new Class[1];
array[0]= xpadro.spring.jms.model.Order.class;
jaxb.setClassesToBeBound(array);
return jaxb;
}
#Bean
#Autowired
public MarshallingMessageConverter marshallingMessageConverter( Jaxb2Marshaller marshaller){
MarshallingMessageConverter mc = new MarshallingMessageConverter();
mc.setMarshaller(marshaller);
mc.setUnmarshaller(marshaller);
return mc;
}
#Bean
#Autowired
public JmsTemplate init(MarshallingMessageConverter messageConverter,ConnectionFactory connectionFactory){
JmsTemplate template = new JmsTemplate();
template.setMessageConverter(messageConverter);
template.setConnectionFactory(connectionFactory);
return template;
}
}
Next, the model:
package xpadro.spring.jms.model;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "order")
#XmlAccessorType(XmlAccessType.FIELD)
public class Order implements Serializable {
private static final long serialVersionUID = -797586847427389162L;
#XmlElement(required = true)
private String id="";
public Order() {
}
public Order(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
Next, the listener:
package xpadro.spring.jms.listener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import xpadro.spring.jms.model.Order;
import xpadro.spring.jms.service.StoreService;
#Component
public class SimpleListener {
private final StoreService storeService;
#Autowired
public SimpleListener(StoreService storeService) {
this.storeService = storeService;
}
#JmsListener(destination = "simple.queue")
public void receiveOrder(Order order) {
storeService.registerOrder(order);
}
}
The class that sends messages:
package xpadro.spring.jms.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;
import xpadro.spring.jms.model.Order;
#Service
public class ClientServiceImpl implements ClientService {
private static final String SIMPLE_QUEUE = "simple.queue";
private static final String IN_QUEUE = "in.queue";
private final JmsTemplate jmsTemplate;
#Autowired
public ClientServiceImpl(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
#Override
public void addOrder(Order order) {
//MessageRegistered with a bean
jmsTemplate.convertAndSend(SIMPLE_QUEUE, order);
}
#Override
public void registerOrder(Order order) {
//MessageRegistered with a bean
jmsTemplate.convertAndSend(IN_QUEUE, order);
}
}
The point is that listener(method receiveOrder()) is not executed when I set a custom message converter in the class JmsJavaconfigApplication. When I dont set it, spring boot sets a SimpleMessageConverter and the listener is executed.
Any wrong or missed configuration?
Thanks
You need to provide an marshalling converter to the #JmsListener to unmarshall the message, by configuring the listener container factory see the documentation.