Closed leomayer closed 3 years ago
The scripts are loaded from the classpath so it should make no difference if they're in src/test/resources
or src/main/resources
as long as the resources in those locations have been placed on the classpath by whatever you're using to run your tests.
We have numerous integration and smoke tests that rely on schema.sql
and data.sql
files being executed and they are all passing so it's not clear to me what may be causing your problem. If you would like us to spend some more time investigating, please spend some time providing a complete yet minimal sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.
I tried to reproduce the issue with a simple project but didn't succeed. I digged little bit deeper and turned on the log level for our real project. I attach the logs to the issue. It seems like the data.sql are exectuted but they are not fetched from the DB. Data which was inserted and could be looked for:
Remark: The logs are up to the point where an JPARepostiory.findAll() was executed. Immediately afterwards a breakpoint was set and the logs ended. While in 2.3.6 the findAll() returned a list of 8 items the 2.3.7 version returned 0 items. Therefore I concluded that the data.sql were not executed. But perhaps the conclusion was too quick and the root cause is somewhere else.
Thanks for the logs. Unfortunately, there's nothing in them that's an immediately obvious reason for the different behaviour. I'm not sure what logging you enabled, but the output doesn't seem to include any Spring Framework or Spring Boot code. For example, I'd expect to see logging from org.springframework.jdbc.datasource.init.ScriptUtils
but didn't see any in either file. Could you change you logging configuration to include org.springframework.jdbc
to confirm whether or not the files are being processed?
I tried to reproduce the issue with a simple project but didn't succeed
This would suggest that the problem's somehow specific to your environment or to your main application's dependencies. The former will make it hard for us to diagnose the problem. The latter will too without a sample with which we can reproduce the problem.
Sorry, I have no clue what kind of options I should enable. I did already on
logging:
level:
root: DEBUG
Since they are not sufficient plz advice which one to set.
That's a strange one too. Root-level debug logging should have been sufficient. I suspect you may have some configuration elsewhere that's overriding that configuration for all but Hibernate and handful of other loggers. Unfortunately, I can't tell if that's definitely the case without knowing more about your application and its configuration. I think we've reached the point where we need a sample that reproduces the problem to make some progress.
The config of the logging is quite strange. The root level is not applied to the sub level - don't know if this is another issue? Anyway config like this included the information you've requested.
logging:
level:
root: DEBUG
org:
hibernate:
SQL: DEBUG
type.descriptor.sql.BasicBinder: TRACE
springframework: DEBUG
If you need other log levels (or format of the output) than plz advice.
boot.2.3.7_jdbc_ROOT.log.gz boot.2.3.6_jdbc_ROOT.log.gz
As mentioned already. The easiest way to find the diff in the log is by search for _PROPERTYEXTENSION
Thanks. On 2.3.6 the data.sql
script was found in target/test-classes
:
09:10:22.671 DEBUG - [ task-2] o.s.jdbc.datasource.init.ScriptUtils :572-Executing SQL script from URL [file:/home.local/lw/workspace-documat/documat-backend/target/test-classes/data.sql]
There's no such log line with 2.3.7. This gives us something to focus on.
The thread being task-2
is interesting and is a notable difference to the 2.3.7 log where everything happens on main
. That's due to https://github.com/spring-projects/spring-boot/issues/24249 but shouldn't affect the discovery of data.sql
scripts. I think we can ignore this for now at least.
As far as I can tell from the logs provided, the data.sql
script isn't on the classpath, i.e. it isn't in target/test-classes
when the application is run. Without a sample to enable me to investigate, you're going to have to do so yourself. If I was you, I would begin that investigation by debugging the application on Spring Boot 2.3.7 with a breakpoint on org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.getResources(String, List<String>, boolean)
. Stepping into the work performed by SortedResourcesFactoryBean
and its ResourcePatternResolver
should let you see what's going on. TRACE
level logging for org.springframework.core.io.support
may also be informative.
Just a few points from my side:
End of my general statement.
Focusing of the issue: Please provide next time a specific yml
configuration for details you are looking for. I'm still not sure if I configured the logs properly.
You mentioned I should set a breakpoint in 2.3.7 - I did so. It stopped as well in 2.3.6. for the DefaultListableBeanFactory
. But the screenshot below is only in 2.3.6 available.
I did little bit of debugging by myself and set a breakpoint in org.springframework.context.support.AbstractApplicationContext line 361:
@Override
public void publishEvent(ApplicationEvent event) {
publishEvent(event, null);
}
for event
I get
2.3.7
org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.web.context.support.GenericWebApplicationContext@10fbbdb, started on Thu Jan 14 12:56:38 CET 2021]
2.3.6
org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.web.context.support.GenericWebApplicationContext@57a2ed35, started on Thu Jan 14 12:59:35 CET 2021]
AND
org.springframework.boot.autoconfigure.jdbc.DataSourceSchemaCreatedEvent[source=HikariDataSource (HikariPool-1)]
Digging further into org.springframework.orm.jpa.AbstractEntityManagerFactoryBean#buildNativeEntityManagerFactory
JpaVendorAdapter jpaVendorAdapter = getJpaVendorAdapter();
if (jpaVendorAdapter != null) {
jpaVendorAdapter.postProcessEntityManagerFactory(emf);
}
org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter@6f4d2294
==>
AbstractJpaVendorAdapter
@Override
public void postProcessEntityManagerFactory(EntityManagerFactory emf) {
}
org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher$DataSourceSchemaCreatedPublisher@53c613f7
with org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher
@Override
public void postProcessEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
this.delegate.postProcessEntityManagerFactory(entityManagerFactory);
AsyncTaskExecutor bootstrapExecutor = this.factoryBean.getBootstrapExecutor();
if (bootstrapExecutor != null) {
DataSourceInitializedPublisher.this.initializationCompletionListener.dataSourceInitialization = bootstrapExecutor
.submit(() -> DataSourceInitializedPublisher.this.publishEventIfRequired(this.factoryBean,
entityManagerFactory));
}
}
For the sake of completeness I included as well the log files with the following settings.
logging:
level:
#root: DEBUG
org:
hibernate:
SQL: DEBUG
type.descriptor.sql.BasicBinder: TRACE
springframework:
jdbc: DEBUG
core:
io: TRACE
orm: TRACE
Thanks.
The missing DataSourceSchemaCreatedEvent
is interesting. It should be published as a result of the LocalContainerEntityManagerFactoryBean
being created. Here's a stack trace captured in my IDE's debugger of when this occurs:
Thread [main] (Suspended)
owns: ConcurrentHashMap<K,V> (id=125)
owns: Object (id=133)
AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).publishEvent(ApplicationEvent) line: 361
DataSourceInitializedPublisher.publishEventIfRequired(LocalContainerEntityManagerFactoryBean, EntityManagerFactory) line: 110
DataSourceInitializedPublisher.postProcessAfterInitialization(Object, String) line: 101
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).applyBeanPostProcessorsAfterInitialization(Object, String) line: 430
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).initializeBean(String, Object, RootBeanDefinition) line: 1798
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 594
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 516
DefaultListableBeanFactory(AbstractBeanFactory).lambda$doGetBean$0(String, RootBeanDefinition, Object[]) line: 324
409598930.getObject() line: not available
DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory<?>) line: 234
DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class<T>, Object[], boolean) line: 322
DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 202
AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).getBean(String) line: 1109
AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).finishBeanFactoryInitialization(ConfigurableListableBeanFactory) line: 869
AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).refresh() line: 551
AnnotationConfigServletWebServerApplicationContext(ServletWebServerApplicationContext).refresh() line: 143
SpringApplication.refresh(ConfigurableApplicationContext) line: 758
SpringApplication.refresh(ApplicationContext) line: 750
SpringApplication.refreshContext(ConfigurableApplicationContext) line: 405
SpringApplication.run(String...) line: 315
SpringApplication.run(Class<?>[], String[]) line: 1237
SpringApplication.run(Class<?>, String...) line: 1226
SampleDataJpaApplication.main(String[]) line: 26
Can you please use the debugger to determine when the event hasn't been published?
I don't understand what you are looking for. As mentioned before - the HibernateJpaVendorAdapter
has no method included. Therefore no Event
is created. Hmmm... I guess I was tooo quick and already answered your question :-)
The event's published in a few different places depending on what sort of initialization is being used. The place that's of interest in this case is the one shown in the stack above:
This is the code in Spring Boot 2.3.7 and it's the call to publishEventIfRequired that should trigger the publication of the event.
Sorry if I'm persistent - but I still guess ....
Well anyway.... In Spring Boot 2.3.7. I neither hit line 90, 93, 96 nor 99.
While in Spring Boot 2.3.6. I hit all of them - before I hit org.springframework.orm.jpa.AbstractEntityManagerFactoryBean#buildNativeEntityManagerFactory
So, what kind information you need next?
That would suggest that the LocalContainerEntityManagerFactoryBean
is being prematurely initialised such that it isn't eligible for post-processing by DataSourceInitializedPublisher
. We'll need a sample that reproduces the problem to identify why that's the case. Alternatively, you could use the debugger with a breakpoint in org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.entityManagerFactory(EntityManagerFactoryBuilder)
to see exactly when the bean is being created and step through its post-processing.
Sorry, but I doubt that the JpaBaseConfiguration.entityManagerFactory
is the proper spot. Since in 2.3.6 this is hit after org.springframework.orm.jpa.AbstractEntityManagerFactoryBean#buildNativeEntityManagerFactory
is hit. But in 2.3.7. it is the other way around.
Why is the order changed from 2.3.6 ==> 2.3.7? Is this somehow related?
Yeah, a sample would be great - but I have honestly no clue what to include and what to provide.
The ordering should not have changed. The entityManagerFactory
@Bean
method should create a LocalContainerEntityManagerFactoryBean
and return it. This bean should then be initialised at which point afterPropertiesSet()
is called on it and it then calls buildNativeEntityManagerFactory()
. If buildNativeEntityManagerFactory()
is being called before the entityManagerFactory
@Bean
method, the only explanation that I can think of is that you have multiple entity manager factories in your application. Furthermore, if org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.entityManagerFactory(EntityManagerFactoryBuilder)
is still being called, then the additional entity manager factory must have been defined in an auto-configuration that runs after HibernateJpaAutoConfiguration
, otherwise Boot's auto-configured entity manager factory should have backed off.
Unfortunately, I don't think I can justify spending any more time trying to help you based on the information that you're currently able to provide. The structure and components of an application are almost impossible to infer from log files alone. If you cannot provide a minimal sample that reproduces the problem, then perhaps you could provide access to the application itself via a private repository on GitHub or similar along with the steps to take to reproduce the problem?
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.
After upgrading from 2.3.6. to 2.3.7. the data.sql scripts are not any longer executed when starting test runs.
The scripts are located in src/test/resources
I've checked this and since I need to load data into my own properties I did it with