Note : I am using PostgreSQL database
After the build and run table is not created in database
I do same as broadleaf documentation for create new entity:
1. **Created new interface** :
package com.mycompany.entity.ordereturn;
public interface OrderReturn {
Long getId();
void setId(Long id);
String getReason();
void setReason(String reason);
String getAddress();
void setAddress(String address);
}
Created new OrderReturnImpl class :
#Entity
#Table(name = "blc_order_return")
public class OrderReturnImpl implements OrderReturn{
#Id
#GeneratedValue(generator= "OrderReturnId")
#GenericGenerator(
name="OrderReturnId",
strategy="org.broadleafcommerce.common.persistence.IdOverrideTableGenerator",
parameters = {
#Parameter(name="segment_value", value="OrderReturnImpl"),
#Parameter(name="entity_name", value="com.mycompany.entity.ordereturn.OrderReturnImpl")
}
)
#Column(name = "OrderReturn_ID")
protected Long id;
#Column(name = "Reason")
protected String reason;
#Column(name = "Address")
protected String address;
#Override
public Long getId() {
// TODO Auto-generated method stub
return id;
}
#Override
public void setId(Long id) {
// TODO Auto-generated method stub
this.id = id;
}
#Override
public String getReason() {
// TODO Auto-generated method stub
return reason;
}
#Override
public void setReason(String reason) {
// TODO Auto-generated method stub
this.reason = reason;
}
#Override
public String getAddress() {
// TODO Auto-generated method stub
return address;
}
#Override
public void setAddress(String address) {
// TODO Auto-generated method stub
this.address = address;
}
}
Configure in persistence-core.xml file :
<persistence-unit name="blPU" transaction-type="RESOURCE_LOCAL">
// Added this line in name = "blPU"
<class>com.mycompany.controller.account.OrderReturnImpl</class>
<exclude-unlisted-classes/>
</persistence-unit>
Although you havent posted your full OrderReturnImpl.java file, you're probably missing the #Entity annotation (along with #Table annotation).
Please annotate your class accordingly.
OK i see a new edit and you now have the annotations. So the error still continues with these annotations?
if you want to create the database tables from the entities, please use
<property name="hibernate.hbm2ddl.auto">create</property>
One possible problem is with creating tables if you are running admin/site on standalone server. Try it on embedded tomcat or jetty.
configure:
In admin/resource/runtime-properties/development.properties
blPU.hibernate.hbm2ddl.auto=create
blCMSStorage.hibernate.hbm2ddl.auto=create
blSecurePU.hibernate.hbm2ddl.auto=create
In core/resource/runtime-properties/common-shared.properties
blPU.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
blSecurePU.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
blCMSStorage.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
blPU.hibernate.hbm2ddl.import_files_sql_extractor=org.broadleafcommerce.common.util.sql.importsql.DemoPostgresSingleLineSqlCommandExtractor
blSecurePU.hibernate.hbm2ddl.import_files_sql_extractor=org.broadleafcommerce.common.util.sql.importsql.DemoPostgresSingleLineSqlCommandExtractor
blCMSStorage.hibernate.hbm2ddl.import_files_sql_extractor=org.broadleafcommerce.common.util.sql.importsql.DemoPostgresSingleLineSqlCommandExtractor
database.properties populated with your data
Be sure to have:
PostgreSQL driver in [standaloneserver]/lib or as a library if you run on embedded servers
Invalidated IDE cache
Clean and install maven goals on all project (or on all three modules)
postgresql start database in pom's executions and postgresql dependency
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>postgres-start</id>
<configuration>
<target>
<echo message="Starting postgres database..."/>
<java fork="true" spawn="true" classname="org.postgresql.Driver"
classpathref="maven.plugin.classpath">
</java>
<echo message="Database started successfully"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4.1211</version>
</dependency>
</dependencies>
Related
I am using Spring Boot 2 to create web application and running the application using CommandLineRunner to connect PostgreSql database
1 . "LinkRepository" Interface:
package com.example.demo;
import org.springframework.data.repository.CrudRepository;
import com.example.entity.Link;
public interface LinkRepository extends CrudRepository<Link, Long> {
}
2. 'Link' Entity :
package com.example.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "link")
public class Link {
#Id
#GeneratedValue
#Column(name = "id")
private Long id;
#Column(name = "NAME")
private String name;
#Column(name = "url", unique = true)
private String url;
public Link(String name, String url) {
this.name = name;
this.url = url;
}
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 getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
3. Demo Application Config:
package com.example.demo;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.example.entity.Link;
#SpringBootApplication(scanBasePackages = { "com.example" })
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Bean
public CommandLineRunner demo(LinkRepository repository) {
// TODO Auto-generated method stub
return (args) -> {
repository.save(new Link("test", "link"));
for (Link linkrepo : repository.findAll()) {
System.out.println(linkrepo.getName());
}
};
}
}
4. 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 https://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.1.7.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</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-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
5. Application.properties :
spring.datasource.url=jdbc:postgresql://localhost:5432/TestDb
spring.datasource.username=postgres
spring.datasource.password=root
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.hibernate.ddl-auto = create
spring.h2.console.enabled=true
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL95Dialect
I am getting following error :
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'demo' defined in com.example.demo.DemoApplication: Unsatisfied dependency expressed through method 'demo' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'linkRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.example.entity.Link
If you want to use CommandLineRunner, then that should be something like this:
`#SpringBootApplication(scanBasePackages = { "com.example" })
public class DemoApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
// TODO Auto-generated method stub
return (args) -> {
repository.save(new Link("test", "link"));
for (Link linkrepo : repository.findAll()) {
System.out.println(linkrepo.getName());
}
};
}
I've just prefer doing that like this:
1) Create a new class called for example DemoBootstrap
2) And it should be soemthing like this
#Component
public class DemoBootstrap implements ApplicationListener<ContextRefreshedEvent> {
private final LinkRepository categoryRepository;
public DemoBootstrap(LinkRepository linkRepository) {
this.linkRepository = linkRepository;
}
#Override
#Transactional
public void onApplicationEvent(ContextRefreshedEvent event) {
// Here add all links that should be saved
// for example
linkRepository.save(new Link("foo", "bar"));
linkRepository.save(new Link("foo2", "bar2"));
// etc
}
Add #EntityScan("com.example.entity") on DemoApplication class or move DemoApplication to 'com.example' package and then spring will scan all sub-packages.
I have a JPA entity called customer and goes like this
#Entity
public class Customer {
private int custNo;
private String custName;
private String country;
public Customer() {
}
public Customer(int custNumber, String custName, String country) {
this.custNo = custNumber;
this.custName = custName;
this.country = country;
}
public int getCustNo() {
return custNo;
}
public void setCustNo(int custNo) {
this.custNo = custNo;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
and my db has 2 tables :- BE132_name and BE1jj231_address ,
I am running my profile liquibase:diff and is giving me the change set as follows
<changeSet author="jobs (generated)" id="1554122585461-10">
<dropTable tableName="BE132_name"/>
</changeSet>
<changeSet author="jobs (generated)" id="1554122585461-11">
<dropTable tableName="BE1jj231_address"/>
</changeSet>
As you can see it created drop table since I dont have its corresponding JPA entities. But why is it not creating the create script for my Customer ?
For an empty data base (one without any tables) , I am getting
INFO 4/2/19 5:47 PM: liquibase: No changes found, nothing to do
I used the liquibase-hibernate plugin for this!. It is capable of generating the changeset for a JPA entity even if its corresponding table is not there in the db.
The plugin
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<propertyFile>src/main/resources/liquibase.properties</propertyFile>
</configuration>
<dependencies>
<dependency>
<groupId>org.liquibase.ext</groupId>
<artifactId>liquibase-hibernate4</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.7.3.RELEASE</version>
</dependency>
</dependencies>
</plugin>
</plugins>
and the liquibase.properties
changeLogFile=classpath:liquibase-changeLog.xml
url=jdbc:mysql://localhost:3306/oauth_reddit
username=tutorialuser
password=tutorialmy5ql
driver=com.mysql.jdbc.Driver
referenceUrl=hibernate:spring:org.baeldung.persistence.model
?dialect=org.hibernate.dialect.MySQLDialect
diffChangeLogFile=src/main/resources/liquibase-diff-changeLog.xml
The referenceUrl is using package scan, so the dialect parameter is required. changeLogFile is the location of changeset for which the db is in sync. diffChangeLogFile is the location where the difference changelog has to be flushed.
I write some code.I want to make questionId field in BaseQuestion Class as Autogenerated.Any solution for that? I am not using jpa jar.so i can't use #Generatedvalue annotation.So how we show here this field is auto generated.
code is below.
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>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>audit_project</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</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-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
BaseQuestion.java
package model;
import java.util.List;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection = "basequestion")
public class BaseQuestion {
#ID
private String id;
private int questionId;
private String responseType;
private boolean required;
private boolean active;
private String questionCode;
private QuestionText questionText;
private String category;
private List<Responses> responses;
public QuestionText getQuestionText() {
return questionText;
}
public void setQuestionText(QuestionText questionText) {
this.questionText = questionText;
}
public List<Responses> getResponses() {
return responses;
}
public void setResponses(List<Responses> responses) {
this.responses = responses;
}
public int getQuestionId() {
return questionId;
}
public void setQuestionId(int questionId) {
this.questionId = questionId;
}
public String getResponseType() {
return responseType;
}
public void setResponseType(String responseType) {
this.responseType = responseType;
}
public boolean getRequired() {
return required;
}
public void setRequired(boolean required) {
this.required = required;
}
public String getQuestionCode() {
return questionCode;
}
public void setQuestionCode(String questionCode) {
this.questionCode = questionCode;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
}
AuditProjectRepository.java
package repository;
import org.springframework.data.mongodb.repository.MongoRepository;
import model.BaseQuestion;
public interface AuditProjectRepository extends MongoRepository<BaseQuestion, String> {
public BaseQuestion findByQuestionId(int questionId);
public BaseQuestion findByQuestionCode(String questionCode);
public Long deleteByQuestionId(int questionid);
}
MongoDB came with all sophisticated ObjectId generation feature, but often you just jumped the ship from relational database, and you still want an easy to read / communicate numeric identifier field which automatically increments every time new record is inserted.
One neat suggestion from MongoDB tutorial is to use a counter collection with a ‘counter name’ as its id, and a ‘seq’ field to store the last used number.
When developing using Spring Data MongoDB, this neat trick can be written as a simple service. Here I used the collection name as the counter name so it’s easy to guess / remember.
import static org.springframework.data.mongodb.core.FindAndModifyOptions.options;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import com.model.CustomSequences;
#Service
public class NextSequenceService {
#Autowired private MongoOperations mongo;
public int getNextSequence(String seqName)
{
CustomSequences counter = mongo.findAndModify(
query(where("_id").is(seqName)),
new Update().inc("seq",1),
options().returnNew(true).upsert(true),
CustomSequences.class);
return counter.getSeq();
}
}
CustomSequences is just a simple class representing the collection. Please beware the usage of int data type, this will limit to 2^31 entries maximum.
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection = "customSequences")
public class CustomSequences {
#Id
private String id;
private int seq;
// getters and setters
}
Then when inserting a new entry (with help of Spring MongoDB Repository support), just set the id field like this before you save it
BaseQuestion baseQuestion = new BaseQuestion();
baseQuestion.setQuestionId(nextSequenceService.getNextSequence("customSequences"));
/* Rest all values */
baseQuestionRepository.save(baseQuestion);
If you don't like this way then you need to use MongoDBEvents and use onBeforeConvert to generate automated value using same above approach.
Also above approach is threadsafe as findAndModify() is a thread safe atomic method
Using a String for your primary key would be a good idea. With this, you do not configure anything since the strings are automatically generated.
In my Spring Boot web application I use MongoDB to store data. In the application I access the database using interfaces that extend MongoRepository.
How do I set up a unit test for such a repository class? What I would like is to
start an embedded/in memory instance of MongoDB
insert testdata from JSON or XML
use an autowired repository to perform queries on the testdata
I have tried using Embedded MongoDB, but I can't figure out how to insert testdata from a file.
I've also tried using NoSQLUnit, but the SpringApplicationConfiguration conflicts with the unit test configuration, resulting in different databases for reading and writing.
Just use #DataMongoTest from Spring Boot.
#RunWith(SpringRunner.class)
#DataMongoTest
public class FooRepositoryTest {
#Autowired
FooRepository fooRepository;
#Before
public void setUp() throws Exception {
fooRepository.save(new Foo());
}
#Test
public void shouldBeNotEmpty() {
assertThat(fooRepository.findAll()).isNotEmpty();
}
}
Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
An update for 2018 and Spring Boot 2. First of all, you can have data-only integration tests with the embedded db as per the documentation. This uses the DataMongoTest annotation. This configures only the necessary dependencies that make mongoDB tests possible.
If you want to do full integration tests, add the AutoConfigureDataMongo annotation instead:
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
#AutoConfigureDataMongo
public class PriceApiControllerIT {
Dependencies you should have in your pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<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-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
This is what I did.
public interface UserRepository extends MongoRepository<Users, Long> {
public void deleteByUserId(String userId);
public List<Users> findAllByUserStatus(String userStatus);
}
#Document
public class Users {
#Id
private long id;
#Transient
public static final String SEQUENCE_NAME = "users_sequence";
#Indexed
#NotNull
private String userId;
private String firstName;
private String lastName;
private String userType;
private String userStatus;
#Email
private String emailId;
#Size(min = 10, max = 10)
#NumberFormat
private String phoneNumber;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public static String getSequenceName() {
return SEQUENCE_NAME;
}
public String getUserStatus() {
return userStatus;
}
public void setUserStatus(String userStatus) {
this.userStatus = userStatus;
}
}
Here is the junit
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = MockodsApplication.class)
#SpringBootTest
#AutoConfigureMockMvc
public class UserControllerIT {
#Autowired
private UserRepository userRepository;
#Autowired
MongoTemplate mongoTemplate;
#Autowired
private MockMvc mvc;
#After
public void tearDown() {
}
#Test
public void test1() {
Users user = new Users();
long userId = 1L;
user.setId(userId);
user.setFirstName("FirstName");
user.setLastName("FirstName");
user.setEmailId("fisrtname.secondname#gmail.com");
user.setPhoneNumber("1234567890");
assertEquals(user, userRepository.save(user));
}
#Test
public void test2() {
List<Users> persistedUser = userRepository.findAll();
assertEquals("fisrtname.secondname#gmail.com", persistedUser.get(0).getEmailId());
}
}
This link helped me to implement https://dzone.com/articles/spring-integration-tests
I faced the same problem and we used a separate MongoConfiguration class to specify a particular configuration for our tests.
You can create an embedded mongo instance by using EmbeddedMongoBuilder like this :
import com.mongodb.Mongo;
import cz.jirutka.spring.embedmongo.EmbeddedMongoBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
import java.net.ServerSocket;
#Configuration
public class MongoConfiguration {
#Bean
public Mongo mongo() throws IOException {
System.setProperty("DB.TRACE","true");
return new EmbeddedMongoBuilder()
.version("2.13.1")
.bindIp("127.0.0.1")
.port(allocateRandomPort())
.build();
}
}
Then in your test class, specify that you want to use that particular configuration with the #Import annotation :
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
#Import(MongoConfiguration.class)
Hope that helps.
Check out https://mongoUnit.org
From its docs:
It's a data driven Integration testing framework for Spring Boot
based applications that use MongoDB for persistence. The framework
enables the developer to test the data access logic with relative
ease.
First, make sure that you have added the following Spring Boot parent to your project:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
Since we added Spring Boot parent, we can add required dependencies without specifying their versions:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
spring-boot-starter-data-mongodb will enable Spring support for
MongoDB
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
de.flapdoodle.embed.mongo provides embedded MongoDB for integration
tests
After adding de.flapdoodle.embed.mongo dependency Spring Boot will automatically try to download and start the embedded MongoDB when running tests. The following snippet shows how you can configure the embedded MongoDB instance manually
class EmbeddedMongoDbIntegrationTest {
private MongodExecutable mongodExecutable;
private MongoTemplate mongoTemplate;
#After
void clean() {
mongodExecutable.stop();
}
#Before
void setup() throws Exception {
String ip = "localhost";
int port = 27017;
IMongodConfig mongodConfig = new MongodConfigBuilder().version(Version.Main.PRODUCTION)
.net(new Net(ip, port, Network.localhostIsIPv6()))
.build();
MongodStarter starter = MongodStarter.getDefaultInstance();
mongodExecutable = starter.prepare(mongodConfig);
mongodExecutable.start();
mongoTemplate = new MongoTemplate(new MongoClient(ip, port), "test");
}
#Test
void test() throws Exception {
// given
DBObject objectToSave = BasicDBObjectBuilder.start()
.add("key", "value")
.get();
// when
mongoTemplate.save(objectToSave, "collection");
// then
assertThat(mongoTemplate.findAll(DBObject.class, "collection")).extracting("key")
.containsOnly("value");
}
}
Note, that we can quickly create MongoTemplate bean configured to use
our manually configured embedded database and register it inside the
Spring container, so your mongo repository will start leveraging this
mongoTemplate as well.
I've been trying to start and stop Jetty automatically in mvn clean install phase for my unit tests. The annoying thing is when I deploy my war file in JBoss all the tests are working fine, however, when I try to use maven-jetty-plugin I have a Connection refuse: connect error. I'm sure about that Jetty starts but doesnt recognize the URLs so that it can't establish the connection.
pom.xml
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.13.v20130916</version>
<configuration>
<webApp>
<contextPath>/</contextPath>
</webApp>
<scanIntervalSeconds>10</scanIntervalSeconds>
<stopKey>foo</stopKey>
<stopPort>9999</stopPort>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
default web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
</web-app>
and my other classes
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import com.buraktas.resource.DefaultBookResource;
#ApplicationPath("/services")
public class BaseApplication extends Application {
private Set<Object> singletons = new HashSet<Object>();
public BaseApplication() {
singletons.add(new DefaultBookResource());
}
#Override
public Set<Object> getSingletons() {
return singletons;
}
}
entity class
public class BookEntity {
private int id;
private String title;
private String author;
private double price;
... setters and getters
}
resource interface
#Path("/book-service")
public interface BookResource {
#POST
#Path("/create")
#Consumes("application/json")
#Produces("application/json")
public BookEntity createBook(BookEntity bookEntity);
}
and the implementation of it
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import com.buraktas.entity.BookEntity;
public class DefaultBookResource implements BookResource {
private Map<Integer, BookEntity> list = new HashMap<Integer, BookEntity>();
private AtomicInteger idCounter = new AtomicInteger();
#Override
public BookEntity createBook(BookEntity bookEntity) {
bookEntity.setId(idCounter.getAndIncrement());
list.put(bookEntity.getId(), bookEntity);
return bookEntity;
}
}
finally test class
public class TestClass {
private static final String POST_INPUT = "{\"title\" : \"LOTR\",\"author\" : \"J.K.Rowling\",\"price\" : 12.99}";
private static Client client;
#Before
public void setUp() {
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
client = Client.create(clientConfig);
}
#After
public void close() {
client.destroy();
}
#Test
public void testCreateSuccess() throws Exception {
WebResource webResourcePost = client.resource("http://localhost:8080/jersey-rest-client/services/book-service/create");
ClientResponse response = webResourcePost.accept("application/json").type("application/json").post(ClientResponse.class, POST_INPUT);
BookEntity responseEntity = response.getEntity(BookEntity.class);
assertEquals(200, response.getStatus());
assertEquals("LOTR", responseEntity.getTitle());
assertEquals("J.K.Rowling", responseEntity.getAuthor());
assertEquals(12.99, responseEntity.getPrice(), 0.0001);
}
}
Also you can find the whole implementation from here
https://github.com/flexelem/jersey-client-example
I will appreciate for every response. Thanks anyway