Error creating bean, Injection of autowired dependencies failed - 500 Internal Server Error - spring

I have created a new Spring project and I have some trouble when I run the application. I am new to Spring development and I thing that the annotations are not placed properly. Any detailed explanation would be great for me for better understating. I am currently reading Spring in action, but if any other book or tutorial seems more accurate, please leave me a comment :)[this is the error that I am getting - 500 Internal Server Error].
This is my project:
HelloWorldConfiguration
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
#EnableWebMvc
#ComponentScan(basePackages = "com.websystique.springmvc")
public class HelloWorldConfiguration {
#Bean(name="HelloWorld")
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
HelloWordInitializer
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class HelloWorldInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(HelloWorldConfiguration.class);
ctx.setServletContext(container);
ServletRegistration.Dynamic servlet = container.addServlet(
"dispatcher", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
}
}
HelloWorldController
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import service.StudentService;
import java.util.HashMap;
import java.util.Map;
#Configuration
#Controller
#ComponentScan(basePackages = "com.websystique.springmvc")
#RequestMapping("/")
public class HelloWorldController {
public HelloWorldController(){
}
#Autowired
private StudentService studentService;
private Map<String, Student> persoaneAdaugate = new HashMap<String, Student>();
#RequestMapping(method = RequestMethod.GET)
public String sayHello(ModelMap model) {
model.addAttribute("greeting", "Hello World from Spring 4 MVC");
return "welcome";
}
#RequestMapping(value = "/helloagain", method = RequestMethod.GET)
public String sayHelloAgain(ModelMap model) {
model.addAttribute("greeting", "Hello World Again, from Spring 4 MVC");
return "welcome";
}
/***
* #ModelAttribute = binds a method parameter or a method return value to a named model attribute and then exposes it to a web view.
* #param student
* #param result
* #param modelMap
* #return
* That is, #ModelAttribute methods are invoked before the controller methods annotated with #RequestMapping are invoked.
* The logic behind the sequence is that, the model object has to be created before any processing starts inside the controller methods.
*/
#RequestMapping(value="/", method = RequestMethod.POST)
public String addStudent(#ModelAttribute("addStudent") Student student, BindingResult result, ModelMap modelMap){
if(result.hasErrors()){
return "error";
}
else {
studentService.addStudent(student);
}
/*modelMap.addAttribute("nume", student.getNume());
modelMap.addAttribute("prenume", student.getPrenume());
persoaneAdaugate.put(student.getNume(), student);
System.out.println("Persoane adaugate: " + persoaneAdaugate +"\n");
System.out.println("nume: " + student.getNume()+" si prenume: " +student.getPrenume());
*/
return "success";
}
}
StudentDao
import com.websystique.springmvc.model.Student;
import org.springframework.stereotype.Component;
import java.util.List;
#Component
public interface StudentDao {
List<Student> getAllStudents();
void addStudent(Student student);
}
StudentDaoImpl
import com.websystique.springmvc.model.Student;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
#Repository("studentDao")
#Service
#Transactional
public class StudentDaoImpl implements StudentDao{
#Autowired
private SessionFactory sessionFactory;
public List<Student> getAllStudents() {
return null;
// return sessionFactory.getCurrentSession().createQuery("from Date").list();
}
public void addStudent(Student student) {
sessionFactory.getCurrentSession().saveOrUpdate(student);
}
}
Student
import org.hibernate.validator.constraints.NotEmpty;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
#Entity
#Table(name="DATE")
public class Student implements Serializable{
#Id
#NotEmpty
#Column(name="nume", unique=true, nullable=false )
private String nume;
#NotEmpty
#Column(name="prenume", nullable = false)
private String prenume;
protected Student(){
}
Student(String nume, String prenume){
this.prenume=prenume;
this.nume=nume;
}
public String getNume(){
return nume;
}
public void setNume(String nume){
this.nume=nume;
}
public String getPrenume(){
return prenume;
}
public void setPrenume(String prenume){
this.prenume=prenume;
}
#Override
public String toString(){
return "Numele adaugat: nume= " + nume +" si prenume= " +prenume;
}
}
StudentService
import com.websystique.springmvc.model.Student;
import org.springframework.stereotype.Component;
import java.util.List;
#Component
public interface StudentService {
List<Student> getAllStudents();
void addStudent(Student student);
}
StudentServiceImpl
import com.websystique.springmvc.dao.StudentDao;
import com.websystique.springmvc.model.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
#Service
#Transactional
public class StudentServiceImpl implements StudentService {
#Autowired
private StudentDao studentDao;
#Transactional
public List<Student> getAllStudents() {
return studentDao.getAllStudents();
}
public void addStudent(Student student) {
studentDao.addStudent(student);
}
}

Related

How to use two data source for same entity in spring boot application running on tomcat

I have one micro-service named order-service in spring boot.
:: Spring Boot :: (v2.0.5.RELEASE)
in that micro-service, in service layer I have 2 service class 1. OrderManagerService and OrderService. From OrderService I call Repository Interface IOrderRequestRepository which extends PagingAndSortingRepository interface. so The call is basically OrderManagerService -> OrderService -> IOrderRequestRepository.
Right now I am using one data source for the micro-service. Now my requirement is I have to use 2 data source because in OrderManagerService there is one method getCustomerVisitsForMonth(Long customerID) which frequently used and we don't want to give load on prod DB server. Instead we will use prod-replica server for this one particular method.
I have googled a lot of blogs and tried to implement but ending up getting different exception.
below are exceptions:
could not execute query; SQL [SELECT * FROM ....(this is the actual query)]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute query",
Could not open JPA EntityManager for transaction; nested exception is org.hibernate.TransactionException: JDBC begin transaction failed:
Below are my sample code:
application-env.properties
spring.datasource.url=jdbc:mysql://someurl:3306/orders?zeroDateTimeBehavior=convertToNull&useSSL=false
spring.datasource.username=<username>
spring.datasource.password=<password>
spring.datasource.driverClassName=com.mysql.jdbc.Driver
#replica datasource details
spring.replica.datasource.url=jdbc:mysql://someurl:3306/order?zeroDateTimeBehavior=convertToNull&useSSL=false
spring.replica.datasource.username=<username>
spring.replica.datasource.password=<password>
spring.replica.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.tomcat.initial-size=15
spring.datasource.tomcat.max-wait=20000
spring.datasource.tomcat.max-active=5
spring.datasource.tomcat.max-idle=4
spring.datasource.tomcat.min-idle=2
spring.datasource.tomcat.default-auto-commit=true
#replica data source details
spring.replica.datasource.tomcat.initial-size=15
spring.replica.datasource.tomcat.max-wait=20000
spring.replica.datasource.tomcat.max-active=5
spring.replica.datasource.tomcat.max-idle=4
spring.replica.datasource.tomcat.min-idle=2
spring.replica.datasource.tomcat.default-auto-commit=true
Main class
package in.demo.order.web.app;
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.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#SpringBootApplication(scanBasePackages = "in.demo.order",
exclude = { SecurityAutoConfiguration.class })
public class OrderServiceApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(OrderServiceApplication.class);
}
}
I have created 2 different packages for Repository classes and for Entity classes, however my Entity and Repository are same.
packages
in.demo.order.dao
in.demo.order.repodao
Configuration classes
MainDataSourceConfiguration
package in.demo.order.web.config;
import in.demo.order.replicadao.IOrderRequestRepositoryForReplica;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
basePackages = "in.demo.order.dao",
entityManagerFactoryRef = "mainEntityManagerFactory",
transactionManagerRef = "mainTransactionManager"
)
public class MainDataSourceConfiguration {
#Autowired
private Environment environment;
#Primary
#Bean(name = "mainDataSourceProperties")
#ConfigurationProperties("spring.datasource")
public DataSourceProperties mainDataSourceProperties() {
return new DataSourceProperties();
}
#Primary
#Bean(name = "mainDataSource")
#ConfigurationProperties("spring.datasource.configuration")
public DataSource mainDataSource(
#Qualifier("mainDataSourceProperties") DataSourceProperties mainDataSourceProperties) {
return mainDataSourceProperties
.initializeDataSourceBuilder()
.type(org.apache.tomcat.jdbc.pool.DataSource.class)
.build();
}
#Primary
#Bean(name = "mainEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean mainEntityManagerFactory(
EntityManagerFactoryBuilder mainEntityManagerFactoryBuilder,
#Qualifier("mainDataSource") DataSource mainDataSource) {
Map<String, String> mainJpaProperties = new HashMap<>();
mainJpaProperties.put("hibernate.dialect",
environment.getProperty("spring.jpa.properties.hibernate.dialect"));
mainJpaProperties.put("hibernate.hbm2ddl.auto",
environment.getProperty("spring.jpa.hibernate.ddl-auto"));
LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = mainEntityManagerFactoryBuilder
.dataSource(mainDataSource)
.packages("in.demo.order.dao.model")
.persistenceUnit("mainDataSource")
.properties(mainJpaProperties)
.build();
localContainerEntityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
return localContainerEntityManagerFactoryBean;
}
#Primary
#Bean(name = "mainTransactionManager")
public PlatformTransactionManager mainTransactionManager(
#Qualifier("mainEntityManagerFactory") EntityManagerFactory mainEntityManagerFactory) {
return new JpaTransactionManager(mainEntityManagerFactory);
}
}
ReplicaDataSourceConfiguration
package in.demo.order.web.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
basePackages = "in.demo.order.replicadao",
entityManagerFactoryRef = "replicaEntityManagerFactory",
transactionManagerRef = "replicaTransactionManager"
)
public class ReplicaDataSourceConfiguration {
#Autowired
private Environment environment;
#Bean(name = "replicaDataSourceProperties")
#ConfigurationProperties("spring.replica.datasource")
public DataSourceProperties replicaDataSourceProperties() {
return new DataSourceProperties();
}
#Bean(name = "replicaDataSource")
#ConfigurationProperties("spring.replica.datasource.configuration")
public DataSource replicaDataSource(
#Qualifier("replicaDataSourceProperties") DataSourceProperties replicaDataSourceProperties) {
return replicaDataSourceProperties
.initializeDataSourceBuilder()
.type(org.apache.tomcat.jdbc.pool.DataSource.class)
.build();
}
#Bean(name = "replicaEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean replicaEntityManagerFactory(
EntityManagerFactoryBuilder replicaEntityManagerFactoryBuilder,
#Qualifier("replicaDataSource") DataSource replicaDataSource) {
Map<String, String> replicaJpaProperties = new HashMap<>();
replicaJpaProperties.put("hibernate.dialect",
environment.getProperty("spring.jpa.properties.hibernate.dialect"));
replicaJpaProperties.put("hibernate.hbm2ddl.auto",
environment.getProperty("spring.jpa.hibernate.ddl-auto"));
LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = replicaEntityManagerFactoryBuilder
.dataSource(replicaDataSource)
.packages("in.demo.order.replicadao.model")
.persistenceUnit("replicaDataSource")
.properties(replicaJpaProperties)
.build();
localContainerEntityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
return localContainerEntityManagerFactoryBean;
}
#Bean(name = "replicaTransactionManager")
public PlatformTransactionManager replicaTransactionManager(
#Qualifier("replicaEntityManagerFactory") EntityManagerFactory replicaEntityManagerFactory) {
return new JpaTransactionManager(replicaEntityManagerFactory);
}
}
OrderManagerService
package in.demo.order.service;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
#Transactional
public class OrderManagerService{
#Autowired
private OrderService orderService;
public CustomerVisitsResponse getCustomerVisitsForMonthForReplicaDataSource(Long customerId) {
return orderService.getTotalCustomerVisitsForMonth(customerId);
}
public CustomerVisitsResponse getCustomerVisitsForMonthForMainDataSource(Long customerId) {
return orderService.getTotalCustomerVisitsForMonthForMainDataSource(customerId);
}
}
OrderService
package in.demo.order.service;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import in.demo.order.replicadao.IOrderRequestRepositoryForReplica;
import in.demo.order.dao.IOrderRequestRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
#Service
#Transactional(rollbackFor = Exception.class)
public class OrderService {
#Autowired
private IOrderRequestRepositoryForMain orderRequestRepositoryForMain;
#Autowired
private IOrderRequestRepositoryForReplica orderRequestRepositoryForReplica;
public CustomerVisitsResponse getTotalCustomerVisitsForMonthForReplicaDataSource(Long customerId) {
List<Integer> statusIdList= new ArrayList<>();
CustomerVisitsResponse response= new CustomerVisitsResponse();
statusIdList.add(OrderServiceConstants.SOME_CONSTANT_VALUE);
List<Integer> sellerIdList= new ArrayList<>();
sellerIdList.add(OrderServiceConstants.SOME_CONSTANT_VALUE);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
Date date = new Date();
String month= dateFormat.format(date)+"%";
try {
List<in.demo.order.replicadao.model.OrderEntity> orders =
orderRequestRepositoryForReplica.getOrderBycustomerIdAndBdMonth(customerId,statusIdList,month,sellerIdList);
if(orders!=null && !orders.isEmpty())
{
double total=0d;
for(in.demo.order.replicadao.model.OrderEntity order:orders)
{
total+=order.getPayableAmount();
}
response.setTotalSpent(total);
response.setTotalVisits((long)(orders.size()));
}
else {
response.setTotalSpent(0d);
response.setTotalVisits(0l);
}
} catch (Exception e) {
logger.info("Error occured while fetching getTotalCustomerVisitsForMonth customerid: " + customerId);
response.setTotalSpent(0d);
response.setTotalVisits(0l);
return response;
}
return response;
}
public CustomerVisitsResponse getTotalCustomerVisitsForMonthForMainDataSource(Long customerId) {
List<Integer> statusIdList= new ArrayList<>();
CustomerVisitsResponse response= new CustomerVisitsResponse();
statusIdList.add(OrderServiceConstants.SOME_CONSTANT_VALUE);
List<Integer> sellerIdList= new ArrayList<>();
sellerIdList.add(OrderServiceConstants.SOME_CONSTANT_VALUE);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
Date date = new Date();
String month= dateFormat.format(date)+"%";
try {
List<in.demo.order.dao.model.OrderEntity> orders =
orderRequestRepositoryForMain.getOrderBycustomerIdAndBdMonth(customerId,statusIdList,month,sellerIdList);
if(orders!=null && !orders.isEmpty())
{
double total=0d;
for(in.demo.order.dao.model.OrderEntity order:orders)
{
total+=order.getPayableAmount();
}
response.setTotalSpent(total);
response.setTotalVisits((long)(orders.size()));
}
else {
response.setTotalSpent(0d);
response.setTotalVisits(0l);
}
} catch (Exception e) {
logger.info("Error occured while fetching getTotalCustomerVisitsForMonth customerid: " + customerId);
response.setTotalSpent(0d);
response.setTotalVisits(0l);
return response;
}
return response;
}
}
Repository classes
package in.demo.order.replicadao;
IOrderRequestRepositoryForReplica
package in.demo.order.replicadao;
import in.demo.order.replicadao.model.OrderEntity;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
#Repository
public interface IOrderRequestRepositoryForReplica extends PagingAndSortingRepository<OrderEntity, Long> {
#Query(nativeQuery = true,
value = "SELECT * FROM orders ...<some query>")
public List<OrderEntity> getOrderBycustomerIdAndBdMonth(
Long customerId, List<Integer> statusIdList, String month, List<Integer> sellerIdList);
}
package in.demo.order.dao;
IOrderRequestRepositoryForMain
package in.demo.order.dao;
import java.util.List;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import in.demo.order.dao.model.OrderEntity;
#Repository
public interface IOrderRequestRepositoryForMain extends PagingAndSortingRepository<OrderEntity, Long> {
#Query(nativeQuery = true,
value = "SELECT * FROM orders ...<some query>")
public List<OrderEntity> getOrderBycustomerIdAndBdMonth(Long customerId,
List<Integer> statusIdList, String month, List<Integer> sellerIdList);
}
Same Entity in different package with different serialVersionUID
packages are:
package in.demo.order.replicadao.model;
package in.demo.order.dao.model;
OrderEntity
package in.demo.order.replicadao.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "orders")
public class OrderEntity implements Serializable {
/**
*
*/
private static final long serialVersionUID = 4667868888563693990L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(unique = true)
private String orderId;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
}
Controller class
OrderController
package in.demo.order.controller;
import java.util.List;
import javax.sql.DataSource;
import in.demo.order.service.OrderManagerService;
#RestController
#RequestMapping("/api/order")
public class OrderController {
#Autowired
private OrderManagerService orderManagerService;
#Autowired
private DataSource mainDataSource;
#Autowired
#Qualifier("replicaDataSource")
private DataSource replicaDataSource;
#GetMapping("/replica")
public CustomerVisitsResponse getCustomerVisitResponseForReplica() {
Long customerId = 123L;
return orderManagerService.getCustomerVisitsForMonthForReplicaDataSource(customerId);
}
#GetMapping("/main")
public CustomerVisitsResponse getCustomerVisitResponseForMain() {
Long customerId = 123L;
return orderManagerService.getCustomerVisitsForMonthForMainDataSource(customerId);
}
#GetMapping("/maindatasource")
public String getMainDataSource() {
return mainDataSource.toString();
}
#GetMapping("/replicadatasource")
public String getReplicaDataSource() {
return replicaDataSource.toString();
}
}
I have checked manually in both Database for the query I am running. Data is present. But when I am running from postman to test
for replica, I am getting
Method threw 'org.springframework.dao.InvalidDataAccessResourceUsageException' exception. caused by org.hibernate.exception.SQLGrammarException: could not execute query
for main, I am getting
Transaction was marked for rollback only; cannot commit; nested exception is org.hibernate.TransactionException: Transaction was marked for rollback only; cannot commit
When I am using one datasource, the query is working fine.
The issue was with Entity class column name mapping issue, previously we were not mentioning #Column(name="column_name") , once I added the annotation, it started to work. But still I am confused how it is working fine when using single Data source

Hibernate / Spring boot: when I update a product, I successfully update the variable I want to modify but the image disappears (which is of type blob)

I am trying to update a product in Postman by changing only the name; when I do this, the name is updated successfully but I notice that the product photo (blob type) that was previously saved when the object was inserted disappears (it is automatically set to null).
How can I solve this problem?
Thank you all
Product.java
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import Model.Product;
#Entity
#Table(name="product")
public class Product {
#Id
private String prodcode;
private String name;
#Lob
private byte[] photo;
public Product() {
}
public Product(String prodcode, String name, byte[] photo) {
this.prodcode = prodcode;
this.name = name;
this.photo = photo;
}
public String getProdcode() {
return prodcode;
}
public void setProdcode(String prodcode) {
this.prodcode = prodcode;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public byte[] getPhoto() {
return photo;
}
public void setPhoto(byte[] photo) {
this.photo = photo;
}
Product_DAO_Imp.java
package DAO;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import Model.Product;
#Repository
public class Product_DAO_Imp implements Product_DAO{
#Autowired
private SessionFactory sessionFactory;
#Override
public boolean updateProduct(Product product) {
boolean status=false;
try {
sessionFactory.getCurrentSession().update(product);
status=true;
} catch (Exception e) {
e.printStackTrace();
}
return status;
}
// ....
// ....
// ....
}
Product_Service_Imp
package Service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import DAO.Product_DAO;
import Model.Product;
#Service
#Transactional
public class Product_Service_Imp implements Product_Service {
#Autowired
private Product_DAO productdao;
#Override
public boolean updateProduct(Product product) {
return productdao.updateProduct(product);
}
// ....
// ....
// ....
}
Controller.java
import java.io.IOException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import Model.Product;
import Service.Product_Service;
#RestController
#CrossOrigin(origins="http://localhost:4200")
#RequestMapping(value="/api")
public class Controller {
#Autowired
private Product_Service productservice;
#PostMapping("update-product/{prodcode}")
public boolean updateProduct(#RequestBody Product product,#PathVariable("prodcode") String prodcode) {
product.setProdcode(prodcode);
return productservice.updateProduct(product);
}
// ....
// ....
// ....
}
You can follow load and save approach to do the desired
It follows below steps
Read the row from DB, using prodcode
update the fields in the above read object and update
You can update the below method in the your Product_DAO_Imp.java
#Override
public boolean updateProduct(Product product) {
boolean status=false;
try {
Product productFrmDb = sessionFactory.getCurrentSession().get(Product.class,product.getProdcode());
productFrmDb.setName(product.getName());
sessionFactory.getCurrentSession().update(productFrmDb);
status=true;
} catch (Exception e) {
e.printStackTrace();
}
return status;
}

How can I implement rsockets to a project with R2DBC in Spring?

I am doing a notifications project with reactive websockets / rsockets in Spring and Vue. But I have not been able to bind my ws to the database. I'm stuck, I need help.
This is my Entity (ProductDto and ProductRequestDto are the same syntax)
package com.example.productservice.entity;
import org.springframework.data.annotation.Id;
import lombok.Data;
import lombok.ToString;
#Data
#ToString
public class Products {
#Id
private Integer id;
private String description;
private Integer price;
private String subscriber;
public Products() {
}
//Getters And Setters
}
This is my repository
package com.example.productservice.repository;
import org.springframework.data.r2dbc.repository.Query;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import org.springframework.stereotype.Repository;
import com.example.productservice.entity.Products;
import reactor.core.publisher.Mono;
#Repository
public interface ProductRepository extends ReactiveCrudRepository<Products, Integer> {
#Query //Example of Query (Ignore this)
("insert into products values (null, :product, :price, :subscriber)")
Mono<Boolean> insert (String product, int price, String subscriber);
}
this is my service (I leave the complete code because I think it can be useful to someone)
package com.example.productservice.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.productservice.dto.ProductDto;
import com.example.productservice.repository.ProductRepository;
import com.example.productservice.util.EntityDtoUtil;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.publisher.Sinks;
#Service
public class ProductService {
#Autowired
private ProductRepository repository;
public Flux<ProductDto> getAll(){
return this.repository.findAll()
.map(EntityDtoUtil::toDto);
}
public Mono<ProductDto> getProductById(final int id){
return this.repository.findById(id)
.map(EntityDtoUtil::toDto);
}
public Mono<ProductDto> insertProduct(Mono<ProductDto> productDtoMono){
return productDtoMono
.map(EntityDtoUtil::toEntity)
.flatMap(this.repository::save)
.map(EntityDtoUtil::toDto);
}
public Mono<ProductDto> updateProduct(int id, Mono<ProductDto> productDtoMono){
return this.repository.findById(id)
.flatMap(p -> productDtoMono
.map(EntityDtoUtil::toEntity)
.doOnNext(e -> e.setId(id)))
.flatMap(this.repository::save)
.map(EntityDtoUtil::toDto);
}
public Mono<Void> deleteProduct (int id) {
return this.repository.deleteById(id);
}
}
and this is my Controller
package com.example.productservice.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
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.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.example.productservice.dto.ProductDto;
import com.example.productservice.service.ProductService;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
#RestController
#RequestMapping("product")
#CrossOrigin(origins= "*", methods = {RequestMethod.GET, RequestMethod.POST})
public class ProductController {
#Autowired
private ProductService service;
#GetMapping("all")
public Flux<ProductDto> all(){
return this.service.getAll();
}
#GetMapping("{id}")
public Mono<ResponseEntity<ProductDto>> getProductById(int id){
return this.service.getProductById(id)
.map(ResponseEntity::ok)
.defaultIfEmpty(ResponseEntity.notFound().build());
}
#PostMapping
public Mono<ProductDto> insertProductTable(#RequestBody Mono<ProductDto> productDtoMono){
return this.service.insertProduct(productDtoMono);
}
#PutMapping("{id}")
public Mono<ResponseEntity<ProductDto>> updateProduct(#PathVariable int id, #RequestBody Mono<ProductDto> productMonoDto) {
return this.service.updateProduct(id, productMonoDto)
.map(ResponseEntity::ok)
.defaultIfEmpty(ResponseEntity.notFound().build());
}
#DeleteMapping
public Mono<Void> deleteProduct(#PathVariable int id){
return this.service.deleteProduct(id);
}
}
So far is my original code functional in the traditional way. I have tried ways to implement rsockets that I leave here:
my applicattion.properties in server side
spring.rsocket.server.port=7000
spring.rsocket.server.transport=tcp
spring.r2dbc.url=r2dbc:mysql://localhost:3306/people2?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.r2dbc.username=root
spring.r2dbc.password=
Modification in ProductService
#Service
public class ProductService {
#Autowired
private ProductRepository repository;
#Autowired
//private Sinks.Many<ProductDto> sink;
#MessageMapping("repository.findAll")
public Flux<ProductDto> getAll(){
return this.repository.findAll()
.map(EntityDtoUtil::toDto);
}
Modification in ProductController client side
#RestController
#RequestMapping("product")
#CrossOrigin(origins= "*", methods = {RequestMethod.GET, RequestMethod.POST})
public class ProductController {
#Autowired
private ProductService service;
private RSocketRequester requester;
#GetMapping("all")
public Flux<ProductDto> all(){
this.requester.route("post.findAll")
.retrieveFlux(ProductDto.class);
return this.service.getAll();
}

Spring boot controller not getting scanned error 404 not found

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.

Spring boot rest : Circular view path [error]: would dispatch back to the current handler URL [/error] again

My issue is I get 404 error when calling the spring boot application on localhost:8080/users
package com.myproj.users.controller;
import java.nio.file.attribute.UserPrincipalNotFoundException;
import java.security.Principal;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.myproj.users.Greeting;
import com.myproj.users.PhysicalCharacteristicsRepository;
import com.myproj.users.UserRepository;
import com.myproj.users.UserResource;
#RestController
#RequestMapping("/users")
public class UserRestController {
private UserRepository userRepository;
private PhysicalCharacteristicsRepository characteristicsRepository;
#RequestMapping(value = "/greeting/", method = RequestMethod.GET)
public String greeting() throws UserPrincipalNotFoundException {
return "Greeting";
}
#RequestMapping(value = "/error/")
public String error() {
return "Error handling";
}
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
#RequestMapping(method = RequestMethod.GET)
public #ResponseBody Greeting sayHello(#RequestParam(value = "name", required = false, defaultValue = "Stranger") String name) {
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
#Autowired
UserRestController(UserRepository userRepository, PhysicalCharacteristicsRepository characteristicsRepository) {
this.userRepository = userRepository;
this.characteristicsRepository = characteristicsRepository;
}
}
package com.myproj.users.controller;
import java.nio.file.attribute.UserPrincipalNotFoundException;
import org.springframework.hateoas.VndErrors;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.weather.exceptions.UserNotFoundException;
#ControllerAdvice
class UserControllerAdvice {
#ResponseBody
#ExceptionHandler(UserNotFoundException.class)
#ResponseStatus(HttpStatus.NOT_FOUND)
VndErrors userNotFoundExceptionHandler(UserNotFoundException ex) {
return new VndErrors("error", ex.getMessage());
}
#ResponseBody
#ExceptionHandler(UserPrincipalNotFoundException.class)
#ResponseStatus(HttpStatus.NOT_FOUND)
VndErrors userPrincipalNotFoundException(UserPrincipalNotFoundException ex) {
return new VndErrors("error", ex.getMessage());
}
}
package com.myproj.users;
public class Greeting {
private final long id;
private final String content;
public Greeting(long id, String content) {
this.id = id;
this.content = content;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
}
I have tested the spring project in https://spring.io/guides/gs/actuator-service/ and it worked so I ignore what's going on.
I have defined a controller to manage errors. I have copied it from Spring Boot Remove Whitelabel Error Page
The new Application class is the following :
package com.test;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#Configuration
#ComponentScan(basePackages = "com.test")
#EnableAutoConfiguration
#EnableJpaRepositories(basePackages = "com.test")
#EntityScan(basePackages = "com.test")
public class Application {
static final Logger logger = LogManager.getLogger(Application.class.getName());
public static void main(String[] args) {
logger.debug("Entered the application");
SpringApplication.run(Application.class, args);
}
private Application() {
}
}
As you can see I have added a controller in ComponentScan as follows :
#ComponentScan(basePackages = "com.test")
#EnableJpaRepositories(basePackages = "com.test")
#EntityScan(basePackages = "com.test")
To test I used curl curl http://localhost:9002/eleves/Hammami/ and firefox.
Changing #Controller to #RestController solved my issue.
In my case I was using thymeleaf(MVC), after that I switched to pure backend.

Resources