During a round of SOUP upgrades in a Spring Boot application, I bumped Apache Derby from 10.14.1.0 to 10.15.1.3. Now the tests fail with this beauty (snipped, full stacktrace here):
Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration':
Unsatisfied dependency expressed through constructor parameter 0
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'dataSource':
Invocation of init method failed
Caused by: java.lang.IllegalStateException:
Failed to replace DataSource with an embedded database for tests.
If you want an embedded database please put a supported one on the
classpath or tune the replace attribute of #AutoConfigureTestDatabase.
What is going here? Do I need to change any configuration?
Apache Derby requires Java 9 from 10.15.x on which Spring Boot does currently not support.
See also spring-boot#16433.
I just want to answer with what it took me to get Derby 15.2.0 to work with Spring Boot 2.4.4 with derby in embedded mode, on top of Java 11. Spring Boot 2.4.4 works out of the box with Derby 14, although you will get some warning as spring boot starts. Upgrading apache derby to 15.2.0 fixed that for me.
In pom, both derby and derbytools dependencies defined:
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.15.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbytools</artifactId>
<version>10.15.2.0</version>
</dependency>
Then in your apps properties file:
spring.datasource.driver-class-name=org.apache.derby.iapi.jdbc.AutoloadedDriver
Instead of:
spring.datasource.driver-class-name=org.apache.derby.jdbc.EmbeddedDriver
After that, I now get a good startup of Spring Boot with no warnings or anything that raises concerns.
I want to enable Hive in my Spring Hadoop project. I understand that we can't use JavaConfiguration so I am using XML. I have an error regarding the Spring Namespace.
Error starting ApplicationContext. To display the auto-configuration
report re-run your application with 'debug' enabled. [2017-10-03
10:26:51.292] - 44342 SEVERE [main] ---
org.springframework.boot.SpringApplication: Application startup failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException:
Configuration problem: Unable to locate Spring NamespaceHandler for
XML schema namespace [http://www.springframework.org/schema/hadoop]
Offending resource: class path resource [hiveContext.xml]
My pom has the following dependency.
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-hadoop-boot</artifactId>
<version>2.5.0.RELEASE</version>
</dependency>
I know some other posts talks about SpringSecurity, but I don't have access to a spring-hadoop-config dependency.
Could you please help me set up connection to the embedded Derby database in Spring Boot application?
I searched the web but can only find solutions for server-type Derby, not for embedded Derby.
spring.jpa.database = ?
spring.jpa.hibernate.ddl-auto = create-drop
Derby as an in-memory database
If you want to Configure in-memory Derby database with spring boot, the minimal thing you need is to mention the runtime dependency (along with spring-boot-starter-data-jpa) as
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<scope>runtime</scope>
</dependency>
This bare minimum configuration should work for any embedded datasource in Spring Boot. But as of current Spring Boot version (2.0.4.RELEASE) this lead to an error only for Derby
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing
DDL via JDBC Statement
Caused by: java.sql.SQLSyntaxErrorException: Schema 'SA' does not exist
This happens because of default configuration ofspring.jpa.hibernate.ddl-auto=create-drop see this spring-boot issue for details.
So you need to override that property in your application.properties as
spring.jpa.hibernate.ddl-auto=update
Derby as a persistent database
If you want to use Derby as your persistent database. Add these application properties
spring.datasource.url=jdbc:derby:mydb;create=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.DerbyTenSevenDialect
spring.jpa.hibernate.ddl-auto=update
You don't need connection properties if you are using Spring Boot. Just add these to your POM:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
</dependency>
Then add the usual controller, service, and repository classes.
How do I configure my Spring Boot application so that when I run unit tests it will use in-memory database such as H2/HSQL but when I run Spring Boot application it will use production database [Postgre/MySQL] ?
Spring profiles can be used for this. This would be a specific way:
Have environment specific properties files:
application.properties:
spring.profiles.active: dev
application-dev.properties
spring.jpa.database: MYSQL
spring.jpa.hibernate.ddl-auto: update
spring.datasource.url: jdbc:mysql://localhost:3306/dbname
spring.datasource.username: username
spring.datasource.password: password
application-test.properties
spring.jpa.database: HSQL
Have both MySQL and H2 drivers in pom.xml, like this:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
Last but not the least, annotate Test classes with #ActiveProfiles("test").
Another approach is to add the annotation #AutoConfigureTestDatabase to you test class.
My tests usually look like this:
#RunWith(SpringRunner.class)
#DataJpaTest
#AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
public class MyRepositoryTest {
#Autowired
MyRepository repository;
#Test
public void test() throws Exception {
// Tests...
}
}
Note that the embedded database dependency needs to be added in the pom.xml file.
For embedded database this annotation is not necessary it will work even if only the dependency is added in pom file.
With #SpringBootTest magic, you just need to do following two changes.
Add 'h2' test dependency in pom.xml
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
Use #AutoConfigureTestDatabase
#RunWith(SpringRunner.class)
#SpringBootTest(classes = MySpringBootApplication.class)
#AutoConfigureTestDatabase
public class SpringBootTest{
#Autowired
private RequestRepository requestRepository;
}
Now all the spring jpa bean/repositories used in test will use h2 as backing database.
2019-04-26 13:13:34.198 INFO 28627 --- [ main]
beddedDataSourceBeanFactoryPostProcessor : Replacing 'dataSource'
DataSource bean with embedded version
2019-04-26 13:13:34.199 INFO 28627 --- [ main]
o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition
for bean 'dataSource'
2019-04-26 13:13:36.194 INFO 28627 --- [ main]
o.s.j.d.e.EmbeddedDatabaseFactory : Starting embedded database:
url='jdbc:h2:mem:2784768e-f053-4bb3-ab88-edda34956893;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false',
username='sa'
Note: I still have 'spring-jpa' properties defined in 'application.properties' and I don't use any profiles. #AutoConfigureTestDatabase will override existing jpa configurations with test defaults AutoConfigureTestDatabase.Replace.
Simplest solution:
1) in src/main/resources have application.properties (production config):
spring.datasource.url=jdbc:mysql://localhost:3306/somedb
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect
and application-test.properties with HSQL config like:
spring.jpa.hibernate.ddl-auto = create-drop
spring.jpa.database = HSQL
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.HSQLDialect
spring.datasource.driverClassName = org.hsqldb.jdbcDriver
spring.datasource.url= jdbc:hsqldb:mem:scratchdb
spring.datasource.username = sa
spring.datasource.password =
2) Add HSQL dependency in pom.xml if you don't have it already.
3) Annotate your test class with #ActiveProfiles("test").
Worked like charm in my case.
#Sanjay has one way to put it but I find it confusing. You could just as well have only a production profile that you enable when you're in production, something like:
spring.jpa.hibernate.ddl-auto: update
spring.datasource.url: jdbc:mysql://localhost:3306/dbname
spring.datasource.username: username
spring.datasource.password: password
And don't specify anything else. If you add an embedded database in test scope, it will be available in your tests. If you run your tests with the default profile (no customization whatsoever), it won't find any database information (since these are stored in the production profile). In that case, it will try to find an embedded database and start it for you. If you need more customization for some reason, you can have a application-test.properties for those (you'll need to add ActiveProfiles("test") to your test(s).
Simple solution if building with maven: just place an application.properties file under src/test/resources and edit as appropriate for testing.
The Spring (Boot) Profile mechanism is a pretty powerful tool that, in scope, goes way beyond "swapping settings between test time and run time". Although, clearly, as demonstrated, it can do that also :)
This solution enables common settings for develop and test. Is based on this solution:
Override default Spring-Boot application.properties settings in Junit Test
application.properties in src/main/resources/application.properties
#common settings for DEVELOPMENT and TEST:
......
......
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url=jdbc:postgresql://localhost:5432/databasename
spring.datasource.username=postgres
spring.datasource.password=somepassword
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = none
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
test.properties (src/main/resources/application.properties) which overrides and adds properties in application.properties:
spring.datasource.url=jdbc:h2:mem:testdb;MODE=PostgreSQL
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=false
settings in pom.xml for H2 and Postgre databases
<!-- h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<!-- postgress -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
In test class:
#RunWith(SpringRunner.class)
#SpringBootTest
#TestPropertySource(locations = "classpath:test.properties")
public class ModelTest {
}
I have a multi-module Gradle SpringBootApplication with below Modules
employeemanagerApp - Where my SpringApplication main class
employeemanagerIntTests - Where i have my cucumber tests
My requirement was to use MySQL DB when the application boots up and H2 during my Cucumber Integration testing
Solution: In my employeemanagerApp module, src/main/resources i placed the application.properties with below content
#My SQL Configuration
spring.datasource.url=jdbc:mysql://localhost:3306/employeemanager
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
And in the Integration Test Module (employeemanagerIntTests) src/test/resources I placed the application.properties with below content
#H2 In-Memory DB Configuration
spring.datasource.url=jdbc:h2://mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.format_sql=true
And in my Step Definition Class i added only these annotations
#CucumberContextConfiguration
#SpringBootTest(classes = SpringBootApplicationMainClass.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
In the build.gradle file i added H2 dependency
testImplementation 'com.h2database:h2:1.4.200'
So when I ran my tests, H2 was active and all tests with Create, Update, Read and Delete were successful
I am trying to setup EHCache in distributed environment with Terracotta. Here I am able to connect Application server and Terracotta server and in terracotta Developer Console I am able to see replicated objects.
But in application server continiously following exception message is appearing, though rest of the application is running properly:
Hi All, if any body can guide why this exception message appears and how we can resolve it.
Also it would be helpful for me have any comprehensive tutorial for setting up terracotta for hibernate application.
Here [CacheByAmitNode8081] is the name of cache node I have defined in application server.
[DEBUG][04/05/12 12:49:07.973][CacheByAmitNode8081] Running mbean initializer task for ehcache hibernate...
[DEBUG][04/05/12 12:49:07.995][CacheByAmitNode8081] Successfully registered bean
[ERROR][04/05/12 12:49:08.000][CacheByAmitNode8081] Error locating Hibernate Session Factory
java.lang.NullPointerException
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:36)
at sun.reflect.UnsafeQualifiedObjectFieldAccessorImpl.get(UnsafeQualifiedObjectFieldAccessorImpl.java:20)
at java.lang.reflect.Field.get(Field.java:358)
at org.hibernate.cache.ehcache.management.impl.ProviderMBeanRegistrationHelper$RegisterMBeansTask.locateSessionFactory(ProviderMBeanRegistrationHelper.java:152)
at org.hibernate.cache.ehcache.management.impl.ProviderMBeanRegistrationHelper$RegisterMBeansTask.run(ProviderMBeanRegistrationHelper.java:117)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
[DEBUG][04/05/12 12:49:08.001][CacheByAmitNode8081] SessionFactory is probably still being initialized... waiting for it to complete before enabling hibernate statistics monitoring via JMX
[DEBUG][04/05/12 12:49:08.001][CacheByAmitNode8081] Running mbean initializer task for ehcache hibernate...
[ERROR][04/05/12 12:49:08.001][CacheByAmitNode8081] Error locating Hibernate Session Factory
java.lang.NullPointerException
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:36)
at sun.reflect.UnsafeQualifiedObjectFieldAccessorImpl.get(UnsafeQualifiedObjectFieldAccessorImpl.java:20)
at java.lang.reflect.Field.get(Field.java:358)
at org.hibernate.cache.ehcache.management.impl.ProviderMBeanRegistrationHelper$RegisterMBeansTask.locateSessionFactory(ProviderMBeanRegistrationHelper.java:152)
at org.hibernate.cache.ehcache.management.impl.ProviderMBeanRegistrationHelper$RegisterMBeansTask.run(ProviderMBeanRegistrationHelper.java:117)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)*
When you using Terracotta, you need to add specific terracotta jars on your classpath that will replace ehcache implementation. In your exception stack I don't see any terracotta classes output...
In my maven dependencies I have:
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core-ee</artifactId>
<version>2.5.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-terracotta-ee</artifactId>
<version>2.5.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.terracotta</groupId>
<artifactId>terracotta-toolkit-1.5-runtime-ee</artifactId>
<version>4.2.0</version>
<scope>compile</scope>
</dependency>
You can also check Terracotta tutorial on how to plug to Hibernate:
http://terracotta.org/documentation/enterprise-ehcache/get-started-hibernate