The following code produces a cyclic dependency error.
#Controller
public class Controllers {
#Autowired
JdbcTemplate jdbcTemplate;
#RequestMapping(value = "/", method = {RequestMethod.GET, RequestMethod.POST})
#ResponseBody
public String map(){
String sql = "INSERT INTO persons " +
"(id, name, surname) VALUES (?, ?, ?)";
Connection conn = null;
jdbcTemplate.execute("INSERT INTO persons (id, name, surname) VALUES (1, \'Name\', \'Surname\')");
return "";
}
#Bean
#Primary
public DataSource dataSource() {
return DataSourceBuilder
.create()
.username("root")
.password("root")
.url("jdbc:mysql://localhost:3306/people")
.driverClassName("com.mysql.jdbc.Driver")
.build();
}
The dependencies of some of the beans in the application context form a cycle:
| org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
↑ ↓
| controllers (field org.springframework.jdbc.core.JdbcTemplate controllers.Controllers.jdbcTemplate)
↑ ↓
| org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration
↑ ↓
| dataSource
└─────┘
but if I do not autowire jdbctemplate and initialize it normally
jdbcTemplate = new JdbcTemplate(dataSource());
then no errors are produced
I have the following gradle dependencies:
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:1.5.3.RELEASE")
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '1.5.2.RELEASE'
compile(group: 'mysql', name: 'mysql-connector-java', version: '6.0.6')
testCompile group: 'junit', name: 'junit', version: '4.12'
}
What is the reason behind the cyclic dependency?
You have a cyclic dependency because the JdbcTemplate needs a DataSource but for the DataSource to be created an instance of the Controllers is needed, but because that needs a JdbcTemplate it cannot be constructed (due to the cyclic dependency).
You are using Spring Boot but apparently trying hard not to. Remove your #Bean method for the DataSource and add the following to the application.properties.
spring.datasource.url=jdbc:mysql://localhost:3306/people
spring.datasource.username=root
spring.datasource.password=root
With this spring boot will provide a preconfigured DataSource for you.
Pro-Tip
Something else you are mixing versions of Spring Boot 1.5.2 and 1.5.3 never mix versions of a framework as that is trouble waiting to happen. Just remove all versions, and assuming you are using Spring Boot with Gradle properly, you will have a single managed version.
Related
I have a Spring Boot REST service and some unit tests written for the data layer. I use the embedded MongoDB dependency to perform the basic CRUD tests for my Repository class:
public interface UserRepository extends MongoRepository<UserEntity, String> {
Optional<UserEntity> findByUsername(String username);
}
I load the data from a JSON file (located under test/java/resources/data) and with the help of an ObjectMapper instance, I load the data into the embedded DB before each test and drop the collection after it's completed:
#DataMongoTest
class UserRepositoryTest {
// the path to the JSON file
private final File USER_DATA_JSON = Paths.get("src", "test", "resources", "data", "UserData.json").toFile();
// used to load a JSON file into a list of Users
private final ObjectMapper objectMapper = new ObjectMapper();
#Autowired
private MongoTemplate mongoTemplate; // makes the interaction with the embedded MongoDB much easier
#Autowired
private UserRepository userRepository;
#BeforeEach
void setUp() throws IOException {
// deserialize the JSON file to an array of users
UserEntity[] users = objectMapper.readValue(USER_DATA_JSON, UserEntity[].class);
// load each user into embedded MongoDB
Arrays.stream(users).forEach(mongoTemplate::save);
}
#AfterEach
void tearDown() {
// drop the users collection
mongoTemplate.dropCollection("users");
}
#Test
void testFindAllSuccess() {
// WHEN
List<UserEntity> users = userRepository.findAll();
// THEN
assertEquals(2, users.size(), "findAll() should return 2 users!");
}
// other test methods
}
In my local environment, everything works just fine, no configuration is needed inside the application.properties file. But when I execute a build on Jenkins, the following error appears for all the Repository tests:
UserRepositoryTest > testFindAllSuccess() FAILED
java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:132
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:800
Caused by: org.springframework.beans.factory.BeanCreationException at ConstructorResolver.java:658
Caused by: org.springframework.beans.BeanInstantiationException at SimpleInstantiationStrategy.java:185
Caused by: java.net.UnknownHostException at InetAddress.java:1642
Caused by: java.net.UnknownHostException at Inet6AddressImpl.java:-2
The build.gradle file dependencies are declared as follows:
implementation 'org.openapitools:openapi-generator-gradle-plugin:5.0.0'
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation "io.springfox:springfox-boot-starter:3.0.0"
implementation('org.modelmapper:modelmapper:2.3.0')
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo'
testImplementation 'io.projectreactor:reactor-test'
compile 'io.springfox:springfox-swagger-ui:3.0.0'
annotationProcessor group: 'org.springframework.boot', name: 'spring-boot-configuration-processor'
compile 'org.mongodb:mongodb-driver-sync'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.security:spring-security-test'
// https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt
implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1'
I assume Spring Boot is not identifying the embedded MongoDB anymore. How can I configure it as simple as possible?
I saw there is a possibility of using containerized MongoDB and test it using #TestContainers, but for now I need to fix this issue since every build fails due to the tests.
LATER EDIT: By activating the --debug option in Jenkins when running the build, I discovered the following cause:
java.net.UnknownHostException: dev096.dev.cloud.******.eu: dev096.dev.cloud.******.eu: Name or service not known
Do you know if I have to add that address to the known hosts to my local machine (etc/hosts) or it should be configured locally with profiles (localhost for development and dev096.dev.cloud.******.eu for production)?
I managed to reproduce the same error locally and, if you haven't solved it yet, this is my take.
Remove all MongoDB custom configurations/properties, then add the following class to your project:
#Configuration
public class MongoTestConfig {
#Bean
MongoProperties properties() {
MongoProperties mongoProperties = new MongoProperties();
mongoProperties.setPort(33333);
mongoProperties.setHost("localhost");
return mongoProperties;
}
}
Make sure you tag your test class (UserRepositoryTest) with these three annotations:
#RunWith(SpringRunner.class)
#DataMongoTest
#Import(MongoTestConfig.class)
#DataMongoTest ignores all other bean definitions so we force the test to include the configuration that we just created using the explicit #Import.
Now the test will be forced to run on localhost. Hope it's going to work for you as it did for me! 😁
If dev096.dev.cloud.******.eu is a host used only in production, then your production server needs to know that host; not your local PC, nor Jenkins.
Ideally, you'd run your Jenkins tests using a 'jenkins' Spring profile, and then define the localhost in application-jenkins.properties.
Unfortunately, none of your solutions worked for me, but I found out later that dev096.dev.cloud.******.eu is the Jenkins instance itself.
The fix was to add an entry in /etc/hosts/ such that the server's IP to be also recognized as dev096.dev.cloud.******.eu
I tried to use the annotation #RefreshScope on my rest controller:
#RestController
#RefreshScope
public class SpringCloudControllerTest {
#Value("${data}")
private String value;
#GetMapping
public ResponseEntity<String> testPropertiesFile(){
return ResponseEntity.ok(value);
}
the #Value annotation refers the application.properties on my remote repository:
management.endpoints.web.exposure.include=*
data=2
if i change my file in this way:
management.endpoints.web.exposure.include=*
data=3
and run the request on my client side http://localhost:8081/actuator/refresh
the response is just:
[
"config.client.version"
]
I don't see any response about my changes and if i run the request
localhost:8081
the response is always "2"
these are my dependency on client side:
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-config', version: '2.2.6.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version:'2.3.7.RELEASE'
thank you all
Solved.
I change my application name file (client side) from application.yml to bootstrap.yml
Now when i run localhost:8081/actuator/refresh i have got this response
[
"config.client.version",
"data",
"spring.cloud.bootstrap.enabled"
]
thank you all
I am facing an issue that has been mentioned before with Spring Boot vs. Hibernate Validation, where autowiring of dependencies inside custom Constraint Validators is not working. From my own debugging, I have noticed that when entity-level validation occurs, Hibernate loads a different ConstraintValidatorManager compared to when Hibernate is performing bean validation for form submits. The latter works fine, the former leads to dependencies of the custom Constraint Validator being null. It seems as if Hibernate is loading one manager from the root context and one from the servlet context. This would explain Hibernate not having any knowledge of the existence of the dependencies autowired in the custom Constraint Validator. If this is true however, I do not understand what is going on, or how to make Hibernate/JPA aware of the Spring context and it's beans.
I am hoping someone could point me in the right direction? I have tried all of the below answers, and much more (e.g. different library versions, configuration methods, static bean loading through a utils class, etc.):
Inject Repository inside ConstraintValidator with Spring 4 and message interpolation configuration
Autowired gives Null value in Custom Constraint validator
Also I have been through the Reference guide for Spring Boot specifically several times, without much luck. There are several cases that mention their Hibernate validation working fine, both for regular bean submits, as well as during entity persisting. Unfortunately, I seem unable to retrieve their exact (Java) configuration they used, but it seems they are using default configuration. I am starting to wonder if this is a specific Spring Boot issue (although it is stated a combination of Spring Validation and Hibernate Validation should work out-of-the-box).
Adding anything like below bean does not solve the issue (default factory being SpringConstraintValidatorFactory ofcourse):
#Bean
public LocalValidatorFactoryBean validator()
{
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
bean.setValidationMessageSource(messageSource());
return bean;
}
Nor does including a bean definition for a Hibernate validator as such:
Autowired gives Null value in Custom Constraint validator
There are many different ways of loading and injecting the desired bean, but if Hibernate is not at all aware of the beans loaded in the context (because it is using a different context?), how to proceed?
Thanks in advance.
UPDATE: Gradle file
buildscript {
ext {
springBootVersion = '2.1.5.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = '<hidden>'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
jcenter()
}
dependencies {
implementation('org.springframework.boot:spring-boot-starter-web')
implementation('org.springframework.boot:spring-boot-starter-tomcat:2.1.5.RELEASE')
implementation('org.springframework.boot:spring-boot-starter-thymeleaf')
implementation('org.springframework.boot:spring-boot-starter-security')
implementation('org.springframework.boot:spring-boot-starter-data-jpa')
implementation('org.springframework.boot:spring-boot-starter-mail')
implementation('org.springframework.session:spring-session-core')
annotationProcessor('org.springframework.boot:spring-boot-configuration-processor')
implementation('org.postgresql:postgresql')
// https://mvnrepository.com/artifact/org.jboss.aerogear/aerogear-otp-java
implementation('org.jboss.aerogear:aerogear-otp-java:1.0.0')
implementation('com.github.mkopylec:recaptcha-spring-boot-starter:2.2.0')
implementation('nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:2.0.5')
implementation('org.thymeleaf.extras:thymeleaf-extras-springsecurity3:3.0.4.RELEASE')
implementation('javax.enterprise:cdi-api:2.0')
runtimeOnly('org.springframework.boot:spring-boot-devtools')
testImplementation('org.springframework.boot:spring-boot-starter-test')
testImplementation('org.springframework.security:spring-security-test')
testImplementation 'org.mockito:mockito-core:2.27.0'
}
There is a way to tell Hibernate to use the same validator by setting javax.persistence.validation.factory
#Configuration
#Lazy
class SpringValidatorConfiguration {
#Bean
#Lazy
public HibernatePropertiesCustomizer hibernatePropertiesCustomizer(final Validator validator) {
return new HibernatePropertiesCustomizer() {
#Override
public void customize(Map<String, Object> hibernateProperties) {
hibernateProperties.put("javax.persistence.validation.factory", validator);
}
};
}
}
That way everything works fine.
Regarding the fix, just to summarize a more extensive/integrated answer for others that are/were dealing with these sorts of issues, my configuration now contains all of these beans:
#Bean
public LocalValidatorFactoryBean validator()
{
LocalValidatorFactoryBean validatorFactory = new LocalValidatorFactoryBean();
validatorFactory.setValidationMessageSource(messageSource());
return validatorFactory;
}
#Bean
public MessageSource messageSource()
{
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
#Bean
public MethodValidationPostProcessor methodValidationPostProcessor()
{
MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
methodValidationPostProcessor.setValidator(validator());
return methodValidationPostProcessor;
}
#Bean
public HibernatePropertiesCustomizer hibernatePropertiesCustomizer()
{
return properties ->
{
properties.put("javax.persistence.validation.factory", validator());
// Add more properties here such as validation groups (see comment for SO example)
};
}
For an example on adding hibernate validation groups to tease apart validation of different life-cycle events (e.g. bean vs. entity), see Hibernate validations on save (insert) only
This is a pretty confusing one. I've read dozens of links that purport to explain how to use #Transactional but I've verified no transaction is being created.
Main.java
#SpringBootApplication
#EnableJpaRepositories(basePackages="com.mypackage")
#EnableTransactionManagement
#EntityScan(basePackages=["com.mypackage"])
#EnableJpaAuditing
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
SubscriptionController.java
#RequestMapping("/api/subscription")
#RestController
public class SubscriptionController {
#Autowired SubscriptionService subscriptionService;
Logger log = LogManager.getLogger(this.getClass().getName());
public Collection<Subscriptions> subscribe(...) {
log.info("transName: " + TransactionSynchronizationManager.getCurrentTransactionName + ", isAlive: " + TransactionSynchronizationManager.isActualTransactionActive());
return subscriptionService.getAllSubscriptions();
}
}
SubscriptionService.java
#Service
public class SubscriptionService {
#Transactional public Collection<Subscription> getAllSubscriptions() {
log.info("transName: " + TransactionSynchronizationManager.getCurrentTransactionName() + ", isAlive: " + TransactionSynchronizationManager.isActualTransactionActive());
//return subscriptions via JPQL queries here
}
}
build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.0.RELEASE")
}
}
plugins {
id 'war'
}
apply plugin: 'org.springframework.boot'
repositories {
mavenCentral()
}
def springVersion = '5.0.3.RELEASE'
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.3.11'
testCompile group: 'junit', name: 'junit', version: '4.12'
compile "org.springframework.security:spring-security-core:${springVersion}", exclude
compile "org.springframework.security:spring-security-config:${springVersion}", exclude
compile "org.springframework.security:spring-security-web:${springVersion}", exclude
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile "org.springframework:spring-test:${springVersion}", exclude
implementation 'org.springframework.boot:spring-boot-starter-web:2.0.5.RELEASE', exclude
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '2.0.5.RELEASE'
compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.11'
compile 'org.liquibase:liquibase-core:3.6.1'
compile 'org.liquibase:liquibase-groovy-dsl:1.2.2'
}
So when I run the api call, I get null, false as the log output. The contract for #Transactional says that the transactional aspect code will be weaved into the annotated transactional method, such that there will be a transaction (and thus an entitymanager and db connection) set up before the method and closed some time afterward. But that is irrelevant becuase shouldn't spring be creating an entitymanager before the controller is run? Both things aren't working here. Neither spring, nor #Transactional, is setting up any transaction. This results in failure to do any kind of query except for what's doable via a subclasses of JpaRepository. Somehow my Jpa repositories are able to set up transactions for their own methods. But what if their results have lazily initialized properties? I need a hibernate session to get those. So I need a transaction.
Try to remove
#EnableJpaRepositories(basePackages="com.mypackage")
#EnableTransactionManagement
SpringBoot should do those things automatically
What class are you using for #Transactional?
You should use org.springframework.transaction.annotation.Transactional.
An out-of-the-box Spring-boot application using spring initializer (https://start.spring.io/) will handle transactions properly. If you make yourself a sandbox with a unit test you can observer that the transaction demarcation done in your example will produce a transaction. Here is my git hub example: https://github.com/skjenco/hibernateSandbox.git
Code:
#Test
#Transactional
public void test() {
logger.info(TransactionSynchronizationManager.getCurrentTransactionName());
.....
For transaction demarcation to work you must be in an object managed by a Spring (Component, Service, Managed Beans, etc). In the case above it appears that you are in a Spring managed service. Using a working sandbox may be helpful in trouble shooting your issue--that is what I have done to solve perplexing hibernate issues.
You may also want to post your pom.xml file. spring-data or spring-tx dependency should be added for auto configurer to create transaction manager. Otherwise explicitly create a transaction manager bean and run the code again.
You can enable TRACE level logs for org.springframework and see if transaction manager is initialized.
Also check transaction interceptor logs. Use logging.level.org.springframework.transaction.interceptor=TRACE
I am trying to use Spring Data JPA with MyBatis. Since there isnt a Vendor Adapter for MyBatis, what is the alternative here?
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.abc.xyz.domain"/>
</bean>
I am getting the below exception when I tried to initialize my application.
Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: No PersistenceProvider specified in EntityManagerFactory configuration, and chosen PersistenceUnitInfo does not specify a provider class name either
Thanks
Mybatis does not implement JPA.
Mybatis is not ORM Framework. JPA is ORM Specification which is implemented by Hibernate, Toplink, Eclipselink . Since Mybatis does not mplement JPA, it does not come under the list of JPA providers.
Hence, you cannot use mybatis as a JPA framework.
Mybatis is a data mapper framework which is completely different framework compared to JPA.
In JPA and ORM frameworks, you map Objects /Entities to the corresponding sql tables and you work on objects and not on tables directly unless you use their native queries.
In mybatis , you play directly with sql data..
Hope this clears the difference between mybatis and JPA.
Hence when you want mybatis with spring data you use spring data mybatis independently and not spring data JPA.
Why not try spring-data-jpa-extra
It provide a dynamic query solution for spring-data-jpa like mybatis, but much easier than mybatis.
I think you would like it : )
Spring Data MyBatis
If you would not like to use a JPA implementation like Spring-Data-JPA module, but you like use Spring-Data you can find Spring-Data-Mybatis a useful project.
I know that this is not precise answer to your question but I hope that this answer can be interesting.
Spring-Data-Mybatis Hatunet version
I am using this project: https://github.com/hatunet/spring-data-mybatis
It fit very well with spring-data-mybatis and it have also the paginated repository.
Work very well on production project.
update 08/2020
The projet as moved to another webspace and evolved: https://github.com/easybest/spring-data-mybatis
Here is the configuration of mybatis and jpa in spring framework. Mybatis and jpa are different framework so you cannot use mybatis as a JPA framework. Feel free to ask any question if you cannot catch up the configuration.
package com.mastering.springbatch.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
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.sql.DataSource;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
basePackages = {"com.mastering.springbatch.dao",
"com.mastering.springbatch.repository"})
#EntityScan("com.mastering.springbatch.entity")
public class DataConfig {
private final String ENTITY_PACKAGE = "com.mastering.springbatch.entity";
private DriverManagerDataSource dataSource;
#Primary
#Bean(value = "customDataSource")
#ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
this.dataSource = dataSource;
return dataSource;
}
#Primary
#Bean(value = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean emf =
new LocalContainerEntityManagerFactoryBean();
emf.setPackagesToScan(ENTITY_PACKAGE);
emf.setDataSource(dataSource());
emf.setJpaVendorAdapter(jpaVendorAdapter());
return emf;
}
#Primary
#Bean(value = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource());
return factoryBean.getObject();
}
#Primary
#Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager() {
JpaTransactionManager tm = new JpaTransactionManager();
tm.setEntityManagerFactory(entityManagerFactory().getObject());
return tm;
}
private JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
jpaVendorAdapter.setShowSql(true);
jpaVendorAdapter.setGenerateDdl(true);
jpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQLDialect");
return jpaVendorAdapter;
}
}
here is the build.gradle file
buildscript {
ext {
springBootVersion = '2.1.8.RELEASE'
springBootDepManagementVersion = '1.0.8.RELEASE'
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath "io.spring.gradle:dependency-management-plugin:${springBootDepManagementVersion}"
}
}
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'java'
apply plugin: 'idea'
group 'com.learning'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
configurations {
implementation.exclude module: "spring-boot-starter-tomcat"
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile 'org.mybatis:mybatis:3.5.0'
compile 'org.mybatis:mybatis-spring:2.0.0'
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-batch")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("mysql:mysql-connector-java:8.0.14")
// implementation("io.springfox:springfox-swagger2:2.7.0")
// implementation("io.springfox:springfox-swagger-ui:2.7.0")
implementation("org.projectlombok:lombok:1.18.10")
annotationProcessor("org.projectlombok:lombok:1.18.10")
compile group: 'commons-io', name: 'commons-io', version: '2.6'
testAnnotationProcessor("org.projectlombok:lombok:1.18.10")
testCompile("junit:junit:4.12")
testCompile("org.mockito:mockito-core:2.1.0")
testCompile("org.springframework.boot:spring-boot-starter-test")
}
springBoot {
buildInfo()
}