Spring boot -Axon framework NoHandlerForCommandException: No Handler for command - spring-boot

I am getting NoHandlerForCommandException: No Handler for command while trying to use Axon framework with Spring boot.
Below are my Java files :
The Rest controller ->
#RestController
#RequestMapping("/product")
public class ProductController {
#Autowired
private CommandGateway gateway;
#PostMapping
public ResponseEntity createProduct(#RequestBody CreateProductModel model) {
CreateProductCommand command=CreateProductCommand.builder()
.price("$123")
.productId(UUID.randomUUID().toString())
.product("Shoe")
.build();
String s=gateway.sendAndWait(command);
return new ResponseEntity<String>(HttpStatus.CREATED);
}
The ProductCreatedEvent object ->
import lombok.Data;
#Data
public class ProductCreatedEvent {
#TargetAggregateIdentifier
private String productId;
private String product;
private String price ;
}
The command class CreateProductCommand ->
#Builder
#Data
public class CreateProductCommand {
#TargetAggregateIdentifier
private final String productId;
private final String product;
private final String price ;
}
The Aggregate class ->
#Aggregate
public class ProductAggregate {
#AggregateIdentifier
private String productId;
private String product;
private String price ;
public ProductAggregate() {
}
#CommandHandler
public ProductAggregate(CreateProductCommand command) {
//TODO: Validation logic can be handled here
ProductCreatedEvent event=new ProductCreatedEvent();
BeanUtils.copyProperties(command, event);
AggregateLifecycle.apply(event);
}
#EventSourcingHandler
public void on(ProductCreatedEvent event) {
this.price=event.getPrice();
this.productId=event.getProductId();
this.product=event.getProduct();
}
}

Related

Spring boot application I can not get data from oracle database it returns [] in postman

Spring boot application I can not get data from oracle database it returns []. In postman, it returns other requests e.g home method in controller class returns correctly. also, the table created by model class the problem is getting data from the table.
Here is the postman result:
I get this in console:
Model class
#Entity // This tells Hibernate to make a table out of this class
public class Userr {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private String email;
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 String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
//Controller Class
#RestController
public class MainController {
#Autowired // This means to get the bean called userRepository
// Which is auto-generated by Spring, we will use it to handle the data
private UserRepository userRepository;
#PostMapping(path="/add") // Map ONLY POST Requests
public #ResponseBody String addNewUser (#RequestParam String name
, #RequestParam String email) {
// #ResponseBody means the returned String is the response, not a view name
// #RequestParam means it is a parameter from the GET or POST request
Userr n = new Userr();
n.setName(name);
n.setEmail(email);
userRepository.save(n);
return "Saved";
}
#GetMapping(path="/all")
public #ResponseBody Iterable<Userr> getAllUsers() {
// This returns a JSON or XML with the users
//
return userRepository.findAll();
}
#GetMapping(path="/al")
public List<Userr> printPersonInfo() {
List<Userr> list = new ArrayList<>();
userRepository.findAll().forEach(list::add);
return list;
}
#RequestMapping("/user")
public String home(){
return "PPPPPP";
}
}
//Repository Class
public interface UserRepository extends CrudRepository<Userr, Integer> {
}
Add #Repository annotation to your UserRepository. It will help with your issue.

null values inserted while auditing

My AuditListener
public class EmployeeAuditListeners {
#PrePersist
public void prePersist(Employee employee){
perform(employee,Action.INSERTED);
}
#PreUpdate
public void preUpdate(Employee employee){
perform(employee,Action.UPDATED);
}
#PreRemove
public void preRemove(Employee employee){
perform(employee,Action.DELETED);
}
#Transactional
public void perform(Employee emp, Action action){
EntityManager em = BeanUtil.getBean(EntityManager.class);
CommonLogs commonLogs = new CommonLogs();
commonLogs.setQuery("new query");
em.persist(commonLogs);
}
}
and My Auditable.class
#MappedSuperclass
#EntityListeners(AuditingEntityListener.class)
public abstract class Auditable<U> {
#CreatedBy
protected U createdBy;
#CreatedDate
#Temporal(TemporalType.TIMESTAMP)
protected Date createdDate;
#LastModifiedBy
protected U lastModifiedBy;
#LastModifiedDate
#Temporal(TemporalType.TIMESTAMP)
protected Date lastModifiedDate;
}
My CommonLogs.class
#Entity
#EntityListeners(AuditingEntityListener.class)
public class CommonLogs extends Auditable<String> {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String query;
public CommonLogs() {
}
public CommonLogs(String query) {
this.query = query;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
}
My Employee.java class
#Entity
#EntityListeners(EmployeeAuditListeners.class)
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String address;
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 String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
and I have a simple Rest Controller
#RestController
#RequestMapping("/api")
public class EmployeeController {
#Autowired
private EmployeeRepository employeeRepository;
#PostMapping("/employees")
public Employee createEmployee(#RequestBody Employee employee){
return employeeRepository.save(employee);
}
}
I want to log it on my table (common_logs) every time i perform some crud operations on my Employee Entity.
the above given example is working to some extent as it successfully stores employee and invokes EmployeeAuditListeners.
but now while saving CommongLog entity i expect it's parent class Auditable to automatically insert createdBy, createdDate etc. for now only query and id is inserted on common_logs table and remaining columns are null.
You can review the documentation for Auditing in here.
To enable the automatic Auditing, you must add the annotation #EnableJpaAuditing in your Application class:
#SpringBootApplication
#EnableJpaAuditing
class Application {
static void main(String[] args) {
SpringApplication.run(Application.class, args)
}
}
If you want the fields #CreatedBy and #LastModifiedBy too, you will also need to implement the AuditorAware<T> interface. For example:
class SpringSecurityAuditorAware implements AuditorAware<User> {
public User getCurrentAuditor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
return null;
}
return ((MyUserDetails) authentication.getPrincipal()).getUser();
}
}

Spring Data JPA Redis : Cannot write custom method based query

I have configured Spring Data JPA with Redis and using RedisRepositories with provides methods like find(), findAll() etc. All these methods seem to be working just fine, but I am not able to write my custom method like.
RedisEntity findByGenderAndGrade(String gender, String grade);
RedisEntity is a simple POJO Entity class. If you want any more info, please let me know in messages.
Following is my entity:
#Data
#RedisHash("test1")
public class RedisEntity implements Serializable {
#Id
#GeneratedValue
private String id;
private String name;
private String gender;
private Integer grade;
}
Repository:
#Repository
public interface TestRepository extends JpaRepository<RedisEntity, String> {
List<RedisEntity> findAllByGender(String gender);
List<RedisEntity> findAllByGrade(Integer grade);
}
Service/Controller:
#Override
public List<RedisEntity> getById(String id) {
return testRepository.findById(id); //returns data perfectly.
}
#Override
public List<RedisEntity> getAllByGender(String gender) {
return testRepository.findAllByGender(gender); //returns []
}
#Override
public void saveEntity(RedisEntity redisEntity) {
testRepository.save(redisEntity); // saves it in redis perfectly.
}
Also,
findByGender and findAllByGender both give [], although I can see data in my redis database and save it as well.
As requested by FrançoisDupire,
#Configuration
public class RedisConfig {
#Autowired
private DeploymentProperties deploymentProperties;
private static Logger logger = LoggerFactory.getLogger(RedisConfig.class);
#Bean
JedisConnectionFactory jedisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration("localhost", 6379);
redisStandaloneConfiguration.setPassword(RedisPassword.of("root"));
return new JedisConnectionFactory(redisStandaloneConfiguration);
}
#Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(jedisConnectionFactory());
return template;
}
}
Also, I had referred this article: Baeldung article on Spring data redis
As mentioned by #JoshJ and verified by myself and others,
The solution to the problem is:
Adding #Indexed annotation
to all those columns/fields which need to be used with all finds.
#Data
#RedisHash("EmployeeDetails")
public class RedisEntity {
#Id
private String employeeId;
private String firstName;
private String lastName;
#Indexed
private String gender;
#Indexed
private String grade;
}
We have the Spring Data Redis Library which provides the scope to write the custom method.Attaching Sample code.
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.0.8.RELEASE</version>
</dependency>
Entity Definition
#Data
#RedisHash("EmployeeDetails")
public class RedisEntity {
#Id
private String employeeId;
private String firstName;
private String lastName;
private String gender;
private String grade;
}
Repository Definition
#Repository
public interface RedisEntityRepository extends CrudRepository<RedisEntity, String>{
List<RedisEntity> findAllByGenderAndGrade(String gender, String grade);
}
Implementation
#Component
public class RedisEntityImpl implements RedisEntityService {
#Autowired
private RedisEntityRepository redisEntityRepository;
#Override
public List<RedisEntity> getAllByGenderAndGrade(String gender, String grade) {
return redisEntityRepository.findAllByGenderAndGrade(gender,grade);
}
}
Properties
spring.cache.type = redis
spring.redis.host = localhost
spring.redis.port = 6379

Spring Boot #JsonIgnore

Can I use the JsonIngore in a RestController Method? if I put the #JsonIgnore in my VO he will ignore this prop in all request, but I want to ignore only in some request: sample:
I have
public class Pedido{
private Long id;
private Date day;
private List<Item> items;
}
public class Item {
private Long id;
private String nome;
}
#RestController
#RequestMapping("/pedido")
public class PedidoController{
#GetMapping(value = "/")
public List<Pedido> findAll(){
//HERE I dont need to return the List<Item>
}
#GetMapping(value = "/{id}")
public Pedido findById(#PathVariable Long id){
//HERE I need to return the List<Item>
}
}
#JsonView is the right solution for you. Here is an example, and code snippet from the link as below
public class View {
interface Summary {}
}
public class User {
#JsonView(View.Summary.class)
private Long id;
#JsonView(View.Summary.class)
private String firstname;
#JsonView(View.Summary.class)
private String lastname;
private String email;
private String address;
}
#RestController
public class MessageController {
#Autowired
private MessageService messageService;
#JsonView(View.Summary.class)
#RequestMapping("/")
public List<Message> getAllMessages() {
return messageService.getAll();
}
#RequestMapping("/{id}")
public Message getMessage(#PathVariable Long id) {
return messageService.get(id);
}
}

LazyInitializationException Spring and Hibernate

I am getting this exception nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.ibm.ro.model.Location.subLocations, could not initialize proxy - no Session.
I do get that upon accessing the collection, the transaction has already been closed that's why the code is throwing this exception. Here is my sample code
#Entity
#Table(name="location")
public class Location extends BaseEntity {
private static final long serialVersionUID = 1L;
private String name;
private List<Location> subLocations;
private Location location;
#Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "location")
public List<Location> getSubLocations() {
return subLocations;
}
public void setSubLocations(List<Location> subLocations) {
this.subLocations = subLocations;
}
#ManyToOne(fetch = FetchType.LAZY)
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
#Override
public String toString() {
return "Location [name=" + name + ", subLocations=" + subLocations
+ "]";
}
}
Here is my DAO:
#Repository("locationDao")
public class LocationDao implements ILocationDao{
#Autowired
private SessionFactory sessionFactory;
#Override
public List<Location> getAll() {
Session sess = getSession();
return sess.createCriteria(Location.class).setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY).list();
}
}
Then here is my service :
#Service("locationService")
#Transactional
public class LocationService implements ILocationService{
#Autowired
ILocationDao dao;
#Override
public List<Location> getAll() {
return dao.getAll();
}
}
Here is the controller where the exception is being thrown:
#Controller
public class BaseController {
#Autowired
ILocationService service;
private static final String VIEW_INDEX = "index";
private final static org.slf4j.Logger logger = LoggerFactory.getLogger(BaseController.class);
#RequestMapping(value = "/", method = RequestMethod.GET)
public String location(ModelMap model) {
logger.debug(service.getAll().toString());
return VIEW_INDEX;
}
}
What can I do to fix the problem without using OpenSessionInViewFilter?
You can iterate your Location inside your service (where you still have your transaction) and call Hibernate.initialize on the elements, the force initialization of a persistent collection.
#Override
public List<Location> getAll() {
List<Location> locations = dao.getAll();
for (Location location : locations ) {
Hibernate.intialize(location.getSubLocations())
}
return locations;
}

Resources