• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

populate batch databases from spring properties , Spring Boot unit test

 
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am setting the property to initilize batch schema to always, but is seems to be ignored. Running the script manually with @Sql  does create these tables
Below are the properties and some code to ilustrate the project. It is strange that the datasource porperties are processed and the datasource can be autowired.

Is there a way to have this property being considered without needing to create the tables by running the script?
Thank you.







pom.xml dependencies for test scope:






 
Saloon Keeper
Posts: 27764
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm not really sure what you mean. Spring Boot has the ability to run 2 SQL scripts at first launch where one script is intended to construct the schema and the other is intended to pre-load data. Those scripts have to be located at a certain pre-defined place in the project (which I'm too lazy to look up).

If I'm reading you correctly, you get what you want when you uncomment the @Sql annotation in your sample. But I'm pretty sure that the @Sql is not pointing to the standard location. So if you always keep your scripts at the place where your @Sql indicates instead of at the standard location, then, yes, I'd expect the default behavior (without @Sql) to not work.
 
harald michael
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, it works with the @Sql annotation. What I would like to have is creating the batch tables using only the "spring.batch.jdbc.initialize-schema=always"  property without @Sql annotations.
This property works in the main application, but in unit tests it is ignored, thus the need to run the script manually.
 
Tim Holloway
Saloon Keeper
Posts: 27764
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ah. As I recall, there's a separate path for SQL scripts when you run the test (so you don't have to reference the production environment while testing).

I don't recall offhand where that is, though generally in Maven, stuff having to do with testing is located in directories under /src/test. You should be able to find the exact location in the Spring Boot docs, though.

NOTE: corrected Maven test path, Was badly mistyped.
 
harald michael
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you for the answers, but I think I did not describe exactly what I am trying to achieve so I try again.
Yes, calling sql files works called with ScriptUtils.executeScript , with @Sql or automatically at the locations Spring is searching for them having the right name at the same time.

But I do not want to do it like this, I just want SpringBoot to use the "spring.batch.jdbc.initialize-schema=always"  property in application.properties (I have created a new one in test/resources) which is read instead of the one in main/resources.
The problem is that batch tables are not initialized through this property , thus it is ignored, despite having a PropertySourcesPlaceholderConfigurer pointing to the application.properties files as can be seen in the first post . So the question is how can I make SpringBoot to use this property and create batch tables?  And this without calling sql scripts.
Thank you.
 
Tim Holloway
Saloon Keeper
Posts: 27764
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you have an application.properties located properly under src/test/resources, then running tests should be using that property file instead of the src/main/resources one.

Your best bet may therefore be to crank up the logging levels on Spring. especially Spring Boot and Spring JDBC and see if it doesn't report where properties are coming from, what their values are and what's being done with them.
 
harald michael
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
yes, that sounds a good plan, as there are for example spring.datasource.. properties which are considered whn runnign the tests.
Will let you know once I have some results.
 
harald michael
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I was able to print out all properties from the different property sources and they are all there, below some of the properties from application.properties.  I have set debug to true in bootstrap.yml and also these two

logging.level.org.springframework.jdbc.core.JdbcTemplate=TRACE
logging.level.org.springframework.batch=TRACE


but in the logs it is not visible what's being done with them.

property source : Config resource 'class path resource [application.properties]' via location 'optional:classpath:/'

logging.level.org.springframework.jdbc.core.JdbcTemplate = TRACE

logging.level.org.springframework.batch = TRACE
spring.datasource.driverClassName = org.h2.Driver
spring.datasource.driver-class-name = org.h2.Driver
spring.datasource.url = jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1
spring.datasource.username =
spring.datasource.password =
spring.datasource.hikari.minimumIdle = 5
spring.datasource.hikari.maximumPoolSize = 2000
spring.datasource.hikari.idleTimeout = 30000
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto = create
spring.jpa.show-sql = false
spring.jpa.properties.hibernate.format_sql = true
spring.jpa.properties.hibernate.type = trace
spring.batch.jdbc.initialize-schema = always



Yes, I think it would be useful to find a way to see what is being done with the properties.
 
Tim Holloway
Saloon Keeper
Posts: 27764
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm a little lost here. Just realized that you're set up for Spring JPA, but you have a "spring.batch.jdbc.initialize-data" directive.

One thing to note, though, is that if you're working with a version of Spring Boot before 2.5, that property was named spring.batch.initialize-data. That is no "jdbc" in the option name.
 
harald michael
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
well according to the spring documentation this is the correct property : https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.data-initialization.batch

also in this question someone says to use "spring.batch.jdbc.initialize-schema" and "spring.batch.initialize-schema is deprecated since 2.5.0 for removal in 2.7.0"
https://stackoverflow.com/questions/33249942/spring-batch-framework-auto-create-batch-table

This property works fine in the main application , the batch tables are created when it is set to 'always', just in the test there must be something with the autoconfiguration which is different.
The spring.datasource.. properties also worked only after a lot of research I found out that this  annotation was needed to be able to have the data source configured from these properties, otherwise it would also be ignored or overriden:


Maybe there is something similar for the batch property..
 
Tim Holloway
Saloon Keeper
Posts: 27764
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I just realized that Spring Batch apparently has its own set of database tables independent of the application's tables and that this is all about ensuring that those tables should be set up and in place, irrespective of how you handle your application tables.

There is a caveat here, though. If you have Spring Data set up to completely construct/destroy the application database, that would include the Spring Batch tables and their contents, so definitely they'd need to be (re-)constructed before use.

At this point it would seem to be most important that your Spring Batch JDBC initialization option name must match the version of Spring Batch that you are using. And it wouldn't hurt to have Maven list the dependencies and their versions as regards what goes into the build, as Maven can end up using a different version than what you expected.
 
harald michael
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well I understand your point, but I am not sure it applies, as  when using the same property in the main application it works and both Hibernate initializes its tables and also batch tables are initialized. I also saw that when the batch property is set to never and the hibernate one to 'create' , the Hibernate entity tables are recreated without affecting batch tables, which is good  I think.
But it looks like something is different in the test case, I think we should look into the   classes of  spring-boot-test-autonfigure-2.5.6.jar   , I saw there is the Autoconfigure stuff including jdbc and property related. I think it would be very useful if we can find a way to log what is being done with the properties as you wrote before, if you have an idea I would be glad to test it. I set logging.level.org.springframework=TRACE  , it logged indeed a lot of stuff, but there was nothing related to how properties are read / handled. As posted before, they are all fonud and read successfully.

Here is the pom with relevant dependncies to this topic with added versions:


 
harald michael
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have enabled this logging:  

logging.level.org.springframework.boot.autoconfigure=TRACE

  which gives the autoconfigure log.

Here is for example hat is logged for the "spring.datasource.url" property:



The spring.batch.jdbc.initialize-schema  property is not present in this output log...  This is what I try to find out, why it is ignored..

I have set breakpoints in this class, but the debugger is not stopping there:  
org.springframework.boot.autoconfigure.batch.BasicBatchConfigurer
 
Tim Holloway
Saloon Keeper
Posts: 27764
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, I was rather afraid of this. It would appear that your configuration option name doesn't match the version of Spring Batch that you are actually running. Which is why I suggested checking the Maven Dependency diagnostics.

Stupid question: Are you running your Spring Batch tests like this: https://docs.spring.io/spring-batch/docs/current/reference/html/testing.html

I noted that there is a special annotation for Spring Batch testing and I would not be surprised to hear that it autonomously sets up its own private test database and tables to run the tests and then destroys them at the end of the tests.
 
harald michael
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
ok, I would be interested to know what makes you think the configuration option name doesn't match the version of Spring Batch .
I have added the 'maven-error-diagnostics' - is this the one you  mean for diagnostics?

Yes, I use the @SpringBatchTest annotation which provides the tables (a job repository object). But with or without this the property is still ignored.
 
Tim Holloway
Saloon Keeper
Posts: 27764
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The problem with a lot of systems like this is that they may simply ignore options that they do not understand. And since this is an "optional" option, it wouldn't say anything if the option name that it actually wanted was missing.

If you're asking about what I said regarding Maven, no, what I meant was the "mvn dependency:tree" goal. It will list what the actual versions of your dependencies are in case you thought you were getting something else. Which often happens when there are internal dependency version conflicts.
 
harald michael
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
ok, i picked here the ones which I found relvant to the question :



 
Tim Holloway
Saloon Keeper
Posts: 27764
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK. I now know what versions of what you are dealing with, but unfortunately the Spring Batch jar is pretty complex so I can only make guesses here.

One possibility is that when running tests, the Spring Batch job data is not being kept in your MySQL database, but rather in an in-memory HSQL database that is created when the test starts, then vanishes when the test ends. It's quite possible, since for tests you really wouldn't need a large job schedule database and tests work best when there's no stale old data to confuse them.

You should be able to confirm if this is what's happening since you'd be able to schedule test jobs and run them even though there were no permanent entries in the MySQL database. If scheduling fails, then that's not it and we'll have to look elsewhere.

I couldn't actually find the initialize-database keyword in any of its forms in the Spring Batch source code so I have no idea who's handling that and whether it works only for production or not.
 
harald michael
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
yes, tests are ran with the h2 in memory database, which works fine. As indicated above, the datasource is successfully created from the spring.datasource... properties by the Autoconfiguration components of Spring Boot / Spring Boot test.

The properties are read by Spring boot at start and then the Autoconfiguration functionality is used in an attempt to autoconfigure as much as possible. So what would help me here would be to find out where the differences are between autoconfiguring main application (where the property is considered) and the test .  As indicated above, the datasource is configured only after setting this annotation:



As you said before it would be helpful to find a log which says how the properties are handled, as they are all being read into the property sources.
 
Tim Holloway
Saloon Keeper
Posts: 27764
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think you need to consider the Spring Batch persistent resources to be a "black box" and simply trust them to work as documented (if not, you yell at the people who created/maintain Spring Batch).

Or, in other words, code your application to use the Spring Batch API to query/modify/create the database tables relating to Spring Batch and use regular JPA for your actual application database data.

It's good that you concerned yourself about such things, but in practical terms, as long as you are not going to be doing development work on Spring Batch itself., I think you're better off not worrying about such details.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic