I have a problem with Spring Boot application. I want to connect a MongoDB database and a MySql database in my Spring boot application. I would to know if it is possible, in positive case How I can make this multiple connection. I had made a try based on an example with Mysql and Post without success. So I'm wondering if someone have an easy example to know the method.
thanks
It is possible to do this.you will have create different configuration for different datasources. This link has good examples on that
http://www.baeldung.com/spring-data-jpa-multiple-databases
Another useful stackoverflow question: Spring Boot Configure and Use Two DataSources
To get started with mongo and mysql , you can follow example from spring.io guides.
https://spring.io/guides/gs/accessing-data-mongodb/
https://spring.io/guides/gs/accessing-data-mysql/
EDIT :
I have created this one example, merging two samples above
package hello;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import hello.model.Customer;
import hello.model.User;
import hello.mongodao.CustomerRepository;
import hello.mysqldao.UserRepository;
#EnableMongoRepositories(basePackageClasses = CustomerRepository.class)
#EnableJpaRepositories (basePackageClasses = UserRepository.class)
#SpringBootApplication
public class Application implements CommandLineRunner {
#Autowired
private CustomerRepository repository;
#Autowired
private UserRepository userRepository;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void run(String... args) throws Exception {
System.out.println("getting data from Mongo");
repository.deleteAll();
// save a couple of customers
repository.save(new Customer("Alice", "Smith"));
repository.save(new Customer("Bob", "Smith"));
// fetch all customers
System.out.println("Customers found with findAll():");
System.out.println("-------------------------------");
for (Customer customer : repository.findAll()) {
System.out.println(customer);
}
System.out.println();
// fetch an individual customer
System.out.println("Customer found with findByFirstName('Alice'):");
System.out.println("--------------------------------");
System.out.println(repository.findByFirstName("Alice"));
System.out.println("Customers found with findByLastName('Smith'):");
System.out.println("--------------------------------");
for (Customer customer : repository.findByLastName("Smith")) {
System.out.println(customer);
}
System.out.println("gettting data from mysql");
userRepository.deleteAll();
// save a couple of customers
userRepository.save(new User("Alice", "Alice#Smith.com"));
userRepository.save(new User("Bob", "Bob#Smith.com"));
// fetch all customers
System.out.println("Users found with findAll():");
System.out.println("-------------------------------");
for (User user : userRepository.findAll()) {
System.out.println(user);
}
}
}
CustomerRepository.java
package hello.mongodao;
import java.util.List;
import org.springframework.data.mongodb.repository.MongoRepository;
import hello.model.Customer;
public interface CustomerRepository extends MongoRepository<Customer, String> {
public Customer findByFirstName(String firstName);
public List<Customer> findByLastName(String lastName);
}
UserRepository.java
package hello.mysqldao;
import org.springframework.data.repository.CrudRepository;
import hello.model.User;
// This will be AUTO IMPLEMENTED by Spring into a Bean called userRepository
// CRUD refers Create, Read, Update, Delete
public interface UserRepository extends CrudRepository<User, Long> {
}
Customer.java
package hello.model;
import org.springframework.data.annotation.Id;
public class Customer {
#Id
public String id;
public String firstName;
public String lastName;
public Customer() {}
public Customer(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
#Override
public String toString() {
return String.format(
"Customer[id=%s, firstName='%s', lastName='%s']",
id, firstName, lastName);
}
}
User.java
package hello.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity // This tells Hibernate to make a table out of this class
public class User {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private String email;
public User() {
// TODO Auto-generated constructor stub
}
public User(String string, String string2) {
// TODO Auto-generated constructor stub
name = string;
email = string2;
}
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;
}
#Override
public String toString() {
return String.format(
"User[id=%s, name='%s', email='%s']",
id, name, email);
}
}
application.properties
spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=jdbc:mysql://localhost:3306/db_example
spring.datasource.username=springuser
spring.datasource.password=ThePassword
spring.data.mongodb.uri=mongodb://localhost:27017/local
You really don't need to make additional config and property files because MongoDB has different property names than sql so all you will need is an application.properties file
application.properties
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/dbName?useUnicode=yes&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=
spring.data.mongodb.uri=mongodb://localhost:27017
spring.data.mongodb.database=dbName
example models
MongoDB document
import org.springframework.data.mongodb.core.mapping.Document;
import javax.persistence.Id;
#Document("Gyros")
public class Gyros {
public Gyros(String description) {
this.description = description;
}
#Id
public String id;
public String description;
}
Mysql JPA entity
import javax.persistence.*;
#Entity
#Table(name = "Kebab")
public class Kebab {
public Kebab(String description) {
this.description = description;
}
public Kebab() {
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public int id;
public String description;
}
MongoDB repository
#Repository
public interface GyrosRepository extends MongoRepository<Gyros, String> {
}
Mysql Jpa repository
#Repository
public interface KebabRepository extends JpaRepository<Kebab, Integer> {
}
TestService
#org.springframework.stereotype.Service
public class Service {
private final GyrosRepository gyrosRepository;
private final KebabRepository kebabRepository;
#Autowired
public Service(GyrosRepository gyrosRepository, KebabRepository kebabRepository) {
this.gyrosRepository = gyrosRepository;
this.kebabRepository = kebabRepository;
}
#PostConstruct
void test() {
this.gyrosRepository.insert(new Gyros("ham ham"));
this.kebabRepository.saveAndFlush(new Kebab("yum yum"));
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>stack</artifactId>
<version>1.0-SNAPSHOT</version>
<name>stackoverflow</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
I also faced the same kind of problem once. I had to connect my spring boot application to two different databases. One was Mongo db and other was Postgres db.
You can see that i have used both JPA as well as spring-boot-starter-data-mongodb. Still my project is running absolutely fine.Hope for you also it work successfully. There are suggestions over the internet to not use JPA but i am not able to use JPA repository without include JPA.
Here I am posting the solution which worked for me.
Hope it helps someone:
application.properties file:
MONGODB (MongoProperties)
spring.data.mongodb.uri=mongodb://XX.XX.XX.XX:27017/testdb
#POSTGRES properties
spring.datasource.platform=postgres
spring.datasource.url= jdbc:postgresql://localhost:5432/database_name
spring.datasource.username=postgres_usr_name
spring.datasource.password=postgres_pwd
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
My pom dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
To access my data Using Repositories:
(i): MONGO REPOSITORY
import org.springframework.data.mongodb.repository.MongoRepository;
public interface MRepositories extends MongoRepository<YourEntityClass, String>{
}
(ii): JPA repository
#Repository public interface PostGresRepo extends JpaRepository<TestEntity,Long> {}
Related
I tried to make a CRUD RESTapi using SpringBoot, Java, Mysql. My code are okay and running in eclipse but when I tried to POST data from POST Man to mysql workbench it always shows the error.
Project name: SpringRestfulWebServiceHibernate
My pom.xml file:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>springmvc_example</groupId>
<artifactId>SpringRestfulWebServiceHibernate</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Problem in POSTMAN
POST: localhost:8080/SpringRestfulWebServiceHibernate/add/
This ERROR MESSAGE is displaying every time:
{
"timestamp": 1567422726395,
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/SpringRestfulWebServiceHibernate/add/"
}
Main Project codes:
src/main/java:
package: springmvc_example.application
class: UserApplication.java
package springmvc_example.application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class UserApplication {
public static void main(String[]args) {
SpringApplication.run(UserApplication.class, args);
}
}
Codes for configuration.
Package: springmvc_example.config
class: HibernateConfig.java
package springmvc_example.config;
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableTransactionManagement
#ComponentScan({ "springmvc_example.config" })
public class HibernateConfig {
#Bean
public LocalSessionFactoryBean sessionFactoryBean(){
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(new String[] { "springmvc_example.model" });
sessionFactoryBean.setHibernateProperties(hibernateProperties());
return sessionFactoryBean;
}
#Bean
public DataSource dataSource(){
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/springrestful");
ds.setUsername("root");
ds.setPassword("djhonseena");
return ds;
}
private Properties hibernateProperties(){
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.format_sql", "false");
return properties;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory s){
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(s);
return txManager;
}
}
Another configuration class:
WebConfig.java
package springmvc_example.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#Configuration
#EnableWebMvc
#ComponentScan({"springmvc_example"})
public class WebConfig {
}
Webinitializer configuration class:
WebInitializer.java
package springmvc_example.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class[] getRootConfigClasses() {
return new Class[]{ WebConfig.class };
}
#Override
protected Class[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[]{ "/" };
}
}
Controller package and class
package: springmvc_example.controller
class: UserController.java
package springmvc_example.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
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.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import springmvc_example.model.User;
import springmvc_example.service.UserService;
#RestController
public class UserController {
#Autowired
UserService userService;
#RequestMapping(value="/user/", method=RequestMethod.GET, headers="Accept=application/json")
public #ResponseBody List getListUser(){
List users = userService.getListUser();
return users;
}
#RequestMapping(value="/add/", method=RequestMethod.POST)
public #ResponseBody User add(#RequestBody User user){
userService.saveOrUpdate(user);
return user;
}
#RequestMapping(value="/update/{id}", method=RequestMethod.PUT)
public #ResponseBody User update(#PathVariable("id") int id, #RequestBody User user){
user.setId(id);
userService.saveOrUpdate(user);
return user;
}
#RequestMapping(value="/delete/{id}", method=RequestMethod.DELETE)
public #ResponseBody User delete(#PathVariable("id") int id){
User user = userService.findUserById(id);
userService.deleteUser(id);
return user;
}
}
Database package and classes:
package: springmvc_example.dao
interface: UserDao.java
package springmvc_example.dao;
import java.util.List;
import springmvc_example.model.User;
public interface UserDao {
public List getListUser();
public void saveOrUpdate(User user);
public void deleteUser(int id);
public User findUserById(int id);
}
Another database class
class: UserDaoImpl.java
package springmvc_example.dao;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import springmvc_example.model.User;
#Repository
public class UserDaoImpl implements UserDao {
#Autowired
private SessionFactory sessionFactory;
protected Session getSession(){
return sessionFactory.getCurrentSession();
}
#SuppressWarnings("unchecked")
public List getListUser() {
Criteria criteria = getSession().createCriteria(User.class);
return (List) criteria.list();
}
public void saveOrUpdate(User user) {
getSession().saveOrUpdate(user);
}
public void deleteUser(int id) {
User user = (User) getSession().get(User.class, id);
getSession().delete(user);
}
public User findUserById(int id) {
return (User) getSession().get(User.class, id);
}
}
Model package and class:
package: springmvc_example.model
class: User
package springmvc_example.model;
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="user")
public class User {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private int id;
#Column(name="name", nullable=true)
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package: springmvc_example.service
interface: UserService.java
package springmvc_example.service;
import java.util.List;
import springmvc_example.model.User;
public interface UserService {
public List getListUser();
public void saveOrUpdate(User user);
public void deleteUser(int id);
public User findUserById(int id);
}
class: UserServiceImpl.java
package springmvc_example.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import springmvc_example.dao.UserDao;
import springmvc_example.model.User;
#Service
#Transactional
public class UserServiceImpl implements UserService {
UserDao userDao;
#Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public List getListUser() {
return userDao.getListUser();
}
public void saveOrUpdate(User user) {
userDao.saveOrUpdate(user);
}
public void deleteUser(int id) {
userDao.deleteUser(id);
}
public User findUserById(int id) {
return userDao.findUserById(id);
}
}
Properties file for mysql database connection
src/main/resources
application.properties
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springrestful
spring.datasource.username=root
spring.datasource.password=djhonseena
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect
spring.jpa.properties.hibernate.id.new_generator_mappings = false
spring.jpa.properties.hibernate.format_sql = true
spring.datasource.validationQuery=SELECT 1
spring.datasource.testOnBorrow=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
Post your request to localhost:8080/add/
Otherwise add a class level #RequestMapping annotation specifying the value of the endpoint.
Spring boot initializes the application the context of /. There's nothing mapped to /SpringRestfulWebServiceHibernate.
To have your request working, simply send a POST to /add/. (since you've mapped with the slash in the end of add/, you have to send exactly with this slash (/add/)).
Now, if you need the context of /SpringRestfulWebServiceHibernate to be used within your requests, simply put the following line in your application.properties:
server.servlet.context-path=/SpringRestfulWebServiceHibernate
I am trying to use a Simple Spring boot application to create Users and save them to the database using Hibernate but i am getting this error.
Can you please direct me to be able to solve this problem ?
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'jpaMappingContext': Invocation of init
method failed; nested exception is java.lang.IllegalArgumentException:
At least one JPA metamodel must be present! at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
My Application includes :
Pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.springboot</groupId>
<artifactId>SpringBootHibernateInt</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath />
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
DataSource COnfiguration:
package com.spring.security.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
#Configuration
#EnableTransactionManagement
public class DataSourceConfig {
#Autowired
Environment env;
#Bean
public DataSource getDataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
ds.setUrl(env.getProperty("spring.datasource.url"));
ds.setUsername(env.getProperty("spring.datasource.username"));
ds.setPassword(env.getProperty("spring.datasource.password"));
return ds;
}
#Bean
public Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put("spring.hibernate.dialect", env.getProperty("spring.hibernate.dialect"));
properties.put("spring.hibernate.show-sql", env.getProperty("spring.hibernate.show-sql"));
properties.put("spring.hibernate.format-sql", env.getProperty("spring.hibernate.format-sql"));
properties.put("spring.hibernate.ddl-auto", env.getProperty("spring.hibernate.ddl-auto"));
return properties;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager htm = new HibernateTransactionManager();
htm.setSessionFactory(getSessionFactory().getObject());
return htm;
}
#Bean
public LocalSessionFactoryBean getSessionFactory() {
LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean();
lsfb.setDataSource(getDataSource());
lsfb.setHibernateProperties(getHibernateProperties());
// lsfb.setAnnotatedClasses(User.class);
lsfb.setPackagesToScan(env.getProperty("entitymanager.packagesToScan"));
return lsfb;
}
}
User.java
package com.spring.security.model;
import javax.persistence.*;
#Entity
#Table(name = "User")
public class User {
public User(String name) {
this.name = name;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
UserDAOImpl.java
package com.spring.security.dao;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.spring.security.model.User;
#Repository
#Transactional
public class UserDAOImpl {
#Autowired
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public User findUser(String userName) {
return (User) sessionFactory.getCurrentSession()
.createQuery("from User where name = " + userName);
}
public void createUser(User user) {
sessionFactory.getCurrentSession()
.save(user);
}
}
Controller
package com.spring.security.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.spring.security.dao.UserDAOImpl;
import com.spring.security.model.User;
#Controller
public class HomeController {
#Autowired
private UserDAOImpl userService;
#RequestMapping(value = "/save")
#ResponseBody
public String create(String name) {
try {
User user = new User(name);
userService.createUser(user);
} catch (Exception ex) {
return ex.getMessage();
}
return "User succesfully saved!";
}
}
Run.java
package com.spring.security;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Run {
public static void main(String[] args) {
SpringApplication.run(Run.class, args);
}
}
Application.properties
################### JDBC Configuration ###############################
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3307/***
spring.datasource.username=***
spring.datasource.password=***
################### Hibernate Configuration ##########################
spring.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.hibernate.show-sql=true
spring.hibernate.format-sql=true
spring.hibernate.ddl-auto=create
entitymanager.packagesToScan = com
As I said in my comment you can remove all the manual data source configuration as Spring Boot will auto configure it all for you. You can also use JPA repositories for what you need. Replace your UserDaoImpl class with a new repository interface:
#Repository
interface UserRepository implements CrudRepository<User, Integer> {
User findByName(String name);
}
Then in your controller:
#Controller
public class HomeController {
#Autowired
private UserRepository userService;
#RequestMapping(value = "/save")
#ResponseBody
public String create(String name, String city) {
try {
User user = new User("JAYESH");
userService.save(user);
} catch (Exception ex) {
return ex.getMessage();
}
return "User succesfully saved!";
}
}
If you really really want to use Hibernate SessionFactory you can do the following:
#Component
public SomeClass {
#Autowired
private EntityManagerFactory emFactory;
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return emFactory.unwrap(SessionFactory.class);
}
}
Spring Boot by Default Enable Auto Configuration class for the data source, you can simply disable this by something like this.
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class,JndiConnectionFactoryAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,JpaRepositoriesAutoConfiguration.class,DataSourceTransactionManagerAutoConfiguration.class})
#ComponentScan
public class SpringBootStarter {
public static void main(String[] args) {
SpringApplication.run(MyBootApplication.class, args);
}
}
This may help you :)
I've got configuration like this (using Maven):
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>springbootPlural</groupId>
<artifactId>das-boot</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>das-boot</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
</dependencies>
</project>
application.properties:
server.port=0 #(for random port)
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.datasource.url=jdbc:mysql://localhost:3306/mojabaza
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
User.class
package com.test.testowa.model;
import org.springframework.data.jpa.domain.AbstractPersistable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
#Entity
public class User extends AbstractPersistable<Long> {
private String userId;
private String userName;
private String password;
public User() {
}
public User(String userId, String userName, String password) {
this.userId = userId;
this.userName = userName;
this.password = password;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
UserController.class
package com.test.testowa.controller;
import com.test.testowa.Service.UserService;
import com.test.testowa.model.User;
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.RestController;
import java.util.List;
#RestController
#RequestMapping("/user")
public class UserController {
private UserService userService;
#Autowired
public UserController(UserService userService) {
this.userService = userService;
}
#RequestMapping("/delete/{id}")
public String deleteUser(#PathVariable Long id)
{
return userService.deleteUser(id);
}
#RequestMapping("/add")
public User addUser(User user)
{
return userService.addUser(user);
}
#RequestMapping("/list/{id}")
public User findOne(#PathVariable Long id)
{
return userService.findOne(id);
}
#RequestMapping("/list")
public List<User> userList()
{
return userService.userList();
}
}
UserServiceImpl.class
package com.test.testowa.Service.impl;
import com.test.testowa.Service.UserService;
import com.test.testowa.model.User;
import com.test.testowa.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
#Service
public class UserServiceImpl implements UserService {
private UserRepository userRepository;
#Autowired
public UserServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}
#Override
public List<User> userList() {
return userRepository.findAll();
}
#Override
public User findOne(Long id) {
return userRepository.findOne(id);
}
#Override
public User addUser(User user) {
return userRepository.save(user);
}
#Override
public String deleteUser(Long id) {
userRepository.delete(id);
return "{'message':'User deleted'}";
}
}
UserRepository.class
package com.test.testowa.repository;
import com.test.testowa.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
UserService.class
package com.test.testowa.Service;
import com.test.testowa.model.User;
import java.util.List;
public interface UserService {
List<User> userList();
User findOne(Long id);
User addUser(User user);
String deleteUser(Long id);
}
Hibernate creates table "user" flawlessly, but when I'm inserting some values in Postman e.g POST -> localhost:43441/shipwrecks/add, with application/json header and body:
{
"id2":1,
"name":"name1",
"description":"desc1"
}
And I'm getting: Hibernate: insert into shipwreck (description, id2, name) values (?, ?, ?) in console. When I'm inserting data in mysql manually everything go well. Also GET ->localhost:43563/shipwrecks/list works well. Did I make a mistake in this code? Maybe wrong version of Spring Boot?
You need to specify the POST method for the add method in the Controller. I assume your User object is null and the data that you put in your request body does not reach your service.
I facing issue when i am getting id after saving the claimDetail object then to get the id of that saved object it is coming 0 . Actually I want get that saved object Id .But it not coming. I did not work with JPA. I have created a Spring Boot application for scheduling .
Here is my ClaimDetails.java entity class:
#Entity
#Table(name = "claimtrans")
public class ClaimTrans {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
claimDetail.setActive(1);
claimDetail.setVersion(new Long(1));
claimDetail.setCreatedBy(new Long(1));
claimDetail.setCreatedDate(new Date());
claimDetailService.saveClaimDetail(claimDetail);
int temp =claimDetail.getID()
temp is 0;
Here is my JpaRepositoryFactory.java:
#Service
public class ClaimDetailService {
private JpaRepositoryFactory jpaRepositoryFactory;
#Autowired
public ClaimDetailService(JpaRepositoryFactory jpaRepositoryFactory) {
this.jpaRepositoryFactory = jpaRepositoryFactory;
}
#Transactional
public void saveClaimDetail(ClaimDetail claimDetail) {
JpaRepository<ClaimDetail, Long> mailAuditLogLongJpaRepository = jpaRepositoryFactory.getRepository(ClaimDetail.class);
mailAuditLogLongJpaRepository.save(claimDetail);
}
public List<ClaimDetail> getAllClaimDetail() {
JpaRepository<ClaimDetail, Long> mailAuditLogLongJpaRepository = jpaRepositoryFactory.getRepository(ClaimDetail.class);
return mailAuditLogLongJpaRepository.findAll();
}
}
Here is my JPA Factory.
#Component
public class JpaRepositoryFactory {
#PersistenceContext
private EntityManager entityManager;
public <T> T getRepository(Class clazz) {
notNull(clazz);
notNull(entityManager);
T crudRepository = (T) new SimpleJpaRepository(clazz, entityManager);
return crudRepository;
}
}
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>org.sam.application.Application</start-class>
<java.version>1.6</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.10</version>
</dependency>
Anyone can help me please how to fix this issue ?
Thanks
Sitansu
The JPA spec doesn't guarantee that the provided entity object will be updated after saving it. To get the saved JPA entity you have to use the return value of the save() method. For example, your service could be changed this way:
#Service
public class ClaimDetailService {
...
#Transactional
public ClaimDetail saveClaimDetail(ClaimDetail claimDetail) {
JpaRepository<ClaimDetail, Long> mailAuditLogLongJpaRepository = jpaRepositoryFactory.getRepository(ClaimDetail.class);
return mailAuditLogLongJpaRepository.save(claimDetail);
}
...
}
And your sample code would be:
claimDetail.setActive(1);
claimDetail.setVersion(new Long(1));
claimDetail.setCreatedBy(new Long(1));
claimDetail.setCreatedDate(new Date());
ClaimDetail savedClaimDetail = claimDetailService.saveClaimDetail(claimDetail);
int temp = savedClaimDetail.getID()
Also, although not directly related to your problem, you don't need to create the Spring Data repositories the way you have done it. Just create your own interface extending JPARepository.
Write a configuration class and do something like this. Use JpaRepository
#Configuration
public class ClaimDetailService {
public interface ClaimDetailRepository extends JpaRepository<Claimtrans, String>{
ClaimDetail findById(String id);
}
#Autowired
ClaimDetailRepository claimDetailRepository;
#Autowired
public void save(){
ClaimTrans claimDetail=new ClaimTrans();
claimDetail.setId(UUID.randomUUID.toString());
claimDetail.setActive(1);
claimDetail.setVersion(new Long(1));
claimDetail.setCreatedBy(new Long(1));
claimDetail.setCreatedDate(new Date());
claimDetailRepository.save(claimDetail);
int temp =claimDetailRepository.findById(claimDetail.getId());
}
}
I am trying to add #NotNull constraint into my Person object but I still can #POST a new Person with a null email. I am using Spring boot rest with MongoDB.
Entity class:
import javax.validation.constraints.NotNull;
public class Person {
#Id
private String id;
private String username;
private String password;
#NotNull // <-- Not working
private String email;
// getters & setters
}
Repository class:
#RepositoryRestResource(collectionResourceRel = "people", path = "people")
public interface PersonRepository extends MongoRepository<Person, String> {
}
Application class:
#SpringBootApplication
public class TalentPoolApplication {
public static void main(String[] args) {
SpringApplication.run(TalentPoolApplication.class, args);
}
}
pom.xml
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.BUILD-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
...
When I #POST a new object via Postman like:
{
"username": "deadpool",
"email": null
}
I still get STATUS 201 created with this payload:
{
"username": "deadpool",
"password": null,
"email": null
....
....
}
I had the same problem, but just enabling validation didn't work for me, this did work with both JPA and MongoDb to save anyone else spending ages on this. Not only does this get validation working but I get a nice restful 400 error rather than the default 500.
Had to add this to my build.gradle dependencies
compile('org.hibernate:hibernate-validator:4.2.0.Final')
and this config class
#Configuration
public class CustomRepositoryRestConfigurerAdapter extends RepositoryRestConfigurerAdapter {
#Bean
public Validator validator() {
return new LocalValidatorFactoryBean();
}
#Override
public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
validatingListener.addValidator("afterCreate", validator());
validatingListener.addValidator("beforeCreate", validator());
validatingListener.addValidator("afterSave", validator());
validatingListener.addValidator("beforeSave", validator());
}
}
i found it better to make my own version of #NotNull annotation which validates empty string as well.
#Documented
#Constraint(validatedBy = NotEmptyValidator.class)
#Target({ElementType.METHOD, ElementType.FIELD})
#Retention(RetentionPolicy.RUNTIME)
public #interface NotEmpty {
String message() default "{validator.notEmpty}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class NotEmptyValidator implements ConstraintValidator<NotEmpty, Object> {
#Override
public void initialize(NotEmpty notEmpty) { }
#Override
public boolean isValid(Object obj, ConstraintValidatorContext cxt) {
return obj != null && !obj.toString().trim().equals("");
}
}
You can either use the following code for validating
#Configuration
#Import(value = MongoAutoConfiguration.class)
public class DatabaseConfiguration extends AbstractMongoConfiguration
{
#Resource
private Mongo mongo;
#Resource
private MongoProperties mongoProperties;
#Bean
public ValidatingMongoEventListener validatingMongoEventListener() {
return new ValidatingMongoEventListener(validator());
}
#Bean
public LocalValidatorFactoryBean validator() {
return new LocalValidatorFactoryBean();
}
#Override
protected String getDatabaseName() {
return mongoProperties.getDatabase();
}
#Override
public Mongo mongo() throws Exception {
return mongo;
}
}
Normally, the #RestRepository will resolve into a controller than handles validation by itself, except if you Override the default behavior or it by including some #HandleBeforeSave, #HandleBeforeCreate, ... into your code.
A solution is to remove the #HandleBeforeSave, #HandleBeforeCreate, ...
and then spring will handle the validation again.
Or if you want to keep them, you can provide a handler for any object validation like this:
#Component
#RepositoryEventHandler
public class EntityRepositoryEventHandler {
#Autowired
private Validator validator;
#HandleBeforeSave
#HandleBeforeCreate
public void validate(Object o) {
Set<ConstraintViolation<Object>> violations = this.validator.validate(o);
if (!violations.isEmpty()) {
ConstraintViolation<Object> violation = violations.iterator().next();
// do whatever your want here as you got a constraint violation !
throw new RuntimeException();
}
}
}