Any way to create DB(derby) in Spring MVC Project? - spring

I am working on a program which uses memory DB(in my case, it is apache derby, is included in jdk 1.6 and further).
I can set resources like dataSource and sqlSession bean to 'root-context.xml', but do not know how to create DB and table.
If table and DB are already exist, I can do CRUD via usual way. However, this time I should make a DB and new Table on first time. I already tried Maker Class and put 'init-method' to create DB and table before was is uploaded, but it does not work.
How can I make a Spring was program which makes Memory DB and Table before running?
P.S.
I really like to use CRUD in Spring way like SqlSessionTemplate or annotation. But almost of derby sample uses PreparedStatement or Statement. If you have any good sample links what I am looking for, share please. Thanks :D

You need to use the jdbc namespace which includes an embedded-database tag with support for Derby out of the box. The tag takes nested script tags to define scripts to run (they are run in the order declared).
<jdbc:embedded-database id="myDB" type="DERBY" >
<jdbc:script location="classpath:sql/schema.sql"/>
<jdbc:script location="classpath:sql/data.sql"/>
</jdbc:embedded-database>

Related

Spring.datasource.initialize=false not working

I am working on spring boot and batch application.
Due to batch, the application tries to connect to datasource
with spring-boot:run.
I want to stop that and tried spring.datasource.initialize=false
Along with this also put spring.batch.job.enabled=false
While the second one works fine, it seems the first one is ignored.
Could someone let me know if there is a way to stop db connection on startup?
Thanks in advance
The problem is, that spring/spring-boot loads the whole spring-context when it is "booted". This means, that all defined spring-beans are loaded into the spring-context during this boot-phase. In the case of spring-batch, this also means that the datasource bean is loaded and, if not turned off by "spring.batch.initializer.enabled=false", the spring-batch tables are initialized.
Generally, you cannot prevent this from happening as soon as you have added your spring-batch-starter to your maven dependencies.
Moreover, I don't understand why you want to prevent this from happening. It is just initialisation taking place and, provided that everything is configured correctly, this shouldn't be a problem at all.
Nonetheless, if you really want to stop the datasource from beeing initialized, you could try the following approach. However, I don't know if this will work.
Spring-Batch needs a datasource that is registered under the name "dataSource" in the spring-context. If no spring-bean with that name is found, it creates its own. But if you provide your own implementation/configuration for it, it will use your spring bean.
What you need to do is, to provide a proxy for a datasource that is loaded lazily and then register it under the name "dataSource" in the context:
#Configuration
public class MySetUp {
#Bean
public DataSource dataSource() {
// ... create your "lazy initializing" datasource
}
}
But - and let me stress that - this nothing that I would recommend and I don't see a good reason, why this should be necessary to do.
Furthermore, you mention that you only want load "initial static index page" (I assume, you are talking about html, right?). However, I don't see a "batch" use case, which should display html-pages. It would probably be better to have two different applications in this case.
Probably you could provide some more information about your use case.
As I understand, you don't want to prevent database connection during application startup.
Instead, you want to prevent execution of batch scripts.
Correct me, please, if I got it wrong.
To prevent execution of batch scripts set:
spring.batch.initializer.enabled=false

Multiple Embedded HSQLDB databases in jUnit errors during build

I'm working on a new Spring Batch (3.0.3.RELEASE) application where there will be multiple databases accessed during the jobs. For testing we are using HSQLDB (2.3.2) as the embedded database.
In my Application context I have the following.
<jdbc:embedded-database id="dataSource">
</jdbc:embedded-database>
<jdbc:embedded-database id="proDataSource">
<jdbc:script location="classpath:script-tables.sql" />
<jdbc:script location="classpath:script-constraints.sql" />
</jdbc:embedded-database>
<jdbc:embedded-database id="altDataSource">
<jdbc:script location="classpath:script-alt-tables.sql" />
</jdbc:embedded-database>
When I run a single test in Eclipse, things are fine. When I build from the command line, after the first test, I get errors
Failed to execute SQL script statement at line 3 of resource class path resource [script-promrkt-promo.sql]
object name already exists: PROMRKT
It appears to me that the population process in EmbeddedDatabaseFactory is receiving an already populated database. From what I can tell is that after each test there is not a SHUTDOWN being executed and HSQLDB is leaving the already populated database in memory.
I have re-reviewed the documentation and in a Spring Doc this does show a explicit shutdown command. But if spring starts up the embedded database when my test starts why doesn't it shut it down when the test completes ?
Is it expected the embedded databases will remain after each unit test for the same application context?
What is the order that spring starts up an embedded database and when is the transactional context initialized?
Do I need to use a database cleaner ?
Can the populate be updated to only populate when the database is first started, and rollback to the original script configuration when my test is complete ( kinda like how the AbstractTransactionalSpringContextTests worked )
Do I need some transactional markers? Spring Batch's JobRepo is properly being populated and destroyed between each test. Why are my custom dataSources not ?
The script the log message is complaining about isn't in your configuration. I presume it's being executed somewhere else? If that's the case, you'll probably need to add #DirtiesContext to your tests so that Spring doesn't cache the context (I'm assuming you're using the SpringJunit4Runner with #ContextConfiguration but can't be sure since your actual test isn't in the question).
If my assumption is correct, Spring caches the context in an effort to improve performance over the running of a unit test suite. If your test modifies the context in a way that can impact other tests (like running scripts in one test that need to be run again in others), you mark the tests with #DirtiesContext and Spring won't cache the context. You can use the annotation at either the method or class level. You can read more about the annotation here: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/test/annotation/DirtiesContext.html
I spent a lot of time looking at this and reading the Spring Framework documentation (gasp!) and tracing through code. There are some interesting changes in 4.1 spring core, especially the testing.
I found out that ApplicationContext(s) are cached at the JVM level now. If a second test asks for a context the TestContext looks first in it's cache to see if some other test has already asked for the identical configuration.
I have some profiles for some of my tests. A test with a different profile but the same #ContextConfiguration causes the that context to be re-loaded with the profile applied. When the "Bean Loader" arrives at creating the embedded databases, the EmbeddedDatabaseFactory does not take into consideration that the embedded database (in memory HSQLDB) may have already been created or cached from previous tests and does not need to be re-initialized.
Therefore I added some logic to the EmbeddedDatabaseFactory.initDatabase() checking if the database already exists before re-initializing & running the DatabasePopulator.
List existingDataBases = org.hsqldb.DatabaseManager.getDatabaseURIs();
boolean isExisting = false;
String localDBName = StringUtils.lowerCase(this.databaseName);
for (Object object : existingDataBases) {
if (object.toString().contains(localDBName)) {
isExisting = true;
break;
}
}
// Now populate the database
if (!isExisting && this.databasePopulator != null) {
( of course this isn't quite kosher for what spring would need but it gets the point across )
In my opinion it looks like an issue partially with the EmbeddedDatabaseFactory and the TestContext caching mechanism. My "jdbc:embedded-database" definitions do not have any profiles associated with them. Why does the cache need to re-create them and not load them out of the existing cached beans?
You can try to force creation of new embedded database by setting unique name with generateUniqueName(true) each time new object is created.
Here is an example:
embeddedDatabase = new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.generateUniqueName(true)
.addScripts("db/sql/create-db.sql", "db/sql/insert-data.sql")
.build();

Testing Hibernate Mappings

I'm using Hibernate to map objects to a legacy schema which contains some ginormous tables via annotations (as XML files are so 2003). Since these classes are so large, yes I occasionally make an occasional typo, which Hibernate doesn't bother to tell me about until I try to run it.
Here's what I've tried:
One: Setting hbm2ddl.auto to "validate":
This causes the String values of the class to validate against varchar(255). Since many of the column types in the database are CHAR(n), this blows up. I would have to add the columnDefinition="CHAR(n)" to several hundred mappings.
Two: Using Unitils.
Importing these via Maven causes imports of dependency libraries which blow up other sections of code. Example: I'm using Hibernate 4.1, but Unitils imported Hibernate 3.2.5 and blew up a UserType.
So, is there another way to do this? I looked at the Unitils code to see if I could simply yank the sections I needed (I do that with apache-commons fairly often when I just need a single method), but that's not a simple task.
Hibernate is configured via a Spring application context.
Any ideas out there?
I would write tests against an in-memory database (HSQLDB, H2) using the Spring testing framework. You'll quickly see any mapping errors when you attempt to run queries against the tables.
The test class would look something like this:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes=MyTestConfig.class)
#TransactionConfiguration(transactionManager="txMgr", defaultRollback=true)
public class MyTest {
#Autowired
private SessionFactory sessionFactory;
// class body...
}
I would configure Hibernate to auto-deploy the tables as part of the tests.

How to connect to HSQL which Spring creates when jdbc:embedded-database is used?

I have a HSQL database which Spring automatically creates for me:
<jdbc:embedded-database id="dataSource" type="HSQL">
<jdbc:script location="classpath:scheme.sql" /
</jdbc:embedded-database>
And now I want to connect to this database. My question is how to do this, because I don't known which address I should use.
This embedded HSQL database is all-in-memory and in-process, therefore accessible only from the Spring Java process. If you want to access the database from another tool as well, for example to check the contents with a database manager, you can start an HSQLDB server with an all-in-memory instance, then connect to the server from Spring and other tools.
This is covered in the HSQLDB Guide http://hsqldb.org/doc/2.0/guide/listeners-chapt.html
The server is started with this command:
java -cp ../lib/hsqldb.jar org.hsqldb.Server --database.0 mem:test --dbname.0 test
You need to create a Spring data source with username "SA" and password "". The database driver and URL (from the same machine) to configure the Spring data source are:
org.hsqldb.jdbcDriver
jdbc:hsqldb:hsql://localhost/test
I recomend you to use external Database, but just in case if you want to use HSQL, then this may will help you http://java.dzone.com/articles/spring-3-makes-use-embedded-easy
Embedded-database is an in memory DB and Spring supports HSQL, H2, and Derby . You could go to their respective site for the connection details .
For H2 see here .
For HSQL see here and here.
As far as I understand , the
<jdbc:embedded-database id="dataSource" type="HSQL">
<jdbc:script location="classpath:scheme.sql" /
</jdbc:embedded-database>
uses an in-memory DB and so is not accessible externally . You'll be able to access this within the same VM and same class loader .
You can connect to the embedded database in the normal fashion, (SQL Developer, SQL Explorer etc); I used my debugger to look at the URL property in the embedded database bean I created with Spring, in your case dataSource. I would think your url would be something along the lines of jdbc:hsqldb:mem:dataSource.
For some people a sufficient solution would be to use the h2 console - as described here:
spring boot default H2 jdbc connection (and H2 console)
You must only remember to set hsqldb drivers where needed. This way the database doesn't have to be started separately. You also don't have to install any additional software to browse it.
you can do like this
final ApplicationContext ctx = new ClassPathXmlApplicationContext("dao-context.xml");
final DataSource dataSource = (DataSource)ctx.getBean("dataSource");
final Connection conn = dataSource.getConnection();

Jdbc Connection Pooling - using multiple schema known at runtime only

I am working on an engine that is doing the following:
gets data provider info from DB (that tells me to what database & schema details to connect to get my data)
use that info to connect to the database and get my data, that later I use to build some XML content.
The standard setup to handle and isolate database connection management would be to create a DataSource bean (I'm using Spring to wire my components) and inject that in my ProviderConfigDao (loads connection config) and ContentDao (loads data using connection details loaded previously). This would nicely isolate the handling of the connections from the actual code, thus the DAO classes not needing to know how and when a connection is created/opened/closed etc.
This setup doesn't work unfortunately, as when I create my connection, I need to be able to specify the database schema. I don't know all the different schemas from the beginning, so I can't create a set of DataSource objects to cover all of them, thus the DataSource object must be created at runtime and it's creation hidden from the users.
The only solution I can think of is:
Have another class/interface (DataSourceProvider) having one method:
//Gets the connection URL as parameter (which includes the schema name).
DataSource getDataSource(String url);
Add a bean in Spring config to provide a custom implementation for it that manages creation of DataSource objects for each schema.
Inject that object to my DAO classes instead of the DataSource object.
It's not a bad solution, but I was wondering if there is maybe support for something like this already in some open source package ... I'd rather use something already done and tested then reinvent the wheel.
Cheers,
Stef.
there's a JDBC Utils to get all the metada from a database org.springframework.jdbc.support.JdbcUtils
parameters:
DataSource
Implementation of org.springframework.jdbc.support.DatabaseMetaDataCallback

Resources