I have written a REST webservice using JAX-RS and I currently prepare my test database using DbUnit. However, if I would now deploy may application, this would not fit my needs anymore. Thus, I am looking for a maven plugin that lets me handle the preparation and update of the production database. So I need something that creates my tables and inserts default data when I deploy my service for the first time and updates the tables when I deploy new releases, when the service is running.
There are a couple of useful frameworks for this usecase.
Have a look at:
FlyWay
and Liquibase
Both can handle your use case quite neatly. The main difference is the way how migrations are defined, flyway uses SQL and Javacode based migrations, Liquibase uses XML.
My personal preference lies with FlyWay, as I find it more natural.
Related
I am using Play 2.4 with the Flyway-Play module.
Is there are way to clean and recreate the database between tests using this plugin? Some of my unit test have database effects which are not trivial to reverse, and it would be nice to be able to start afresh after these tests.
The documentation for the flyway-play module states:
In Test mode, migration is done automatically.
However, this seems be only once before running all tests. It would be nice to have programmatic control when preparing and cleaning up tests.
Not sure how flyway is integrated in the play framework (no experience with that), but it looks like what you are looking for is the flyway cleancommand.
Drops all objects in the configured schemas.
Flyway documentation: clean
I am working on a Spring Webflow programming using MySQL has the database.
I have some jUnit test cases that Maven runs on the build that uses a test database base not the dev database. we have a diff database for running the projects in dev then the builds.
I have some test data that I need setup in dev before running my project. I was using jUnit for it as part of the package/test in maven but the issue is that test is using diff xml and database. how do you think I can go about making the project remove some delete in dev before running.. Does anyone know of any MySQL plugin for maven that will run a script before?
I'm not entirely sure what you're asking, but I think you want to have certain data available in a DB when you run tests and that data is different in different environments.
Given you're already using maven I would suggest you set up build profiles for each environment, which will allow you to specify different DB connections, indeed if you implement an ORM such as hibernate, you can even get the DB schema and data dropped and recreated on each run in your test / dev environments.
Further more, in environments where you want the data to be specific to your test run and the data does not need to persist beyond the scope of your tests, implement an in memory DB, such as HSQL which can be seeded with data as required and wiped at the end, this will make your development environment more suitable for larger numbers of developers and remove the need for physical DB resources.
I think you're asking about how to set up a database before running a Junit test. If so, I suggest you look at DBUnit and (as suggested in another answer) an in-memory database.
I have a war file with my webapp and I need to generate the database tables in MySQL in the moment when I have copied the war to the webapps folder from Tomcat (assuming Tomcat is running).
Is there a way to do this, can you help me with some information about this?
PS. It's a very simple webapp, using just JDBC, i don't use any ORM frameworks. Is it possible with JDBC?
If you just want to update the schema, but don't want to introduce something as heavyweight as Hibernate, there are some good alternatives:
Flyway - Provide migration scripts with your application to update it at deployment time.
Liquibase - Provide XML description of your schema, and allow Liquibase to update the schema.
Flyway requires you to write the SQL to migrate between different versions of your application. It doesn't generate any DDL (SQL for modifying the schema) at all. It just runs the SQL you give it. If you're comfortable with SQL, and want to be able to use all the features your database provides, I can strongly recommend this.
The code to start the migration can be put into a ServletContextListener. Example code that could be used there is given on the Flyway Application Integration page.
Liquibase works by reading an XML file describing the schema changes necessary to upgrade your database to the latest schema. These changes are applied in order. This means that your schema and changes are more likely to be portable to other databases, but it's arguably harder to take advantage of features that are specific to your database.
Liquibase provides its own ServletContextListener that you can use. See the ServletListener page in the docs.
If you do want to introduce an ORM, you could look at:
Hibernate - ORM with lots of features (and quite a few dependencies)
EclipseLink - previously Oracle TopLink. This seems more polished than Hibernate, but has fewer features.
Do the job in the contextInitialized() method of a custom ServletContextListener class. This will be invoked when the webapp starts up.
#WebListener
public class Config implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent event) {
// Just write/call JDBC code here the usual way to create database/tables if not exists.
}
// ...
}
That said, using an ORM framework like JPA/Hibernate really saves you from a lot of JDBC boilerplate code and headaches.
sounds like a case for : http://www.hibernate.org/
My application is always developing, so occasionally - when the version upgrades - some tables need to be created/altered/deleted, some data modified, etc. Generally some sql code needs to be executed.
Is there a Java library that can be used to keep my database structure up to date (by analyzing something like "db structure version" information and executing custom sql to code to update from one version to another)?
Also it would be great to have some basic actions (like add/remove column) ready to use with minimal configuration, ie name/type and no sql code.
Try DBDeploy. Although I haven't used it in the past, it sounds like this project would help in your case. DBDeploy is a database refactoring manager that:
"Automates the process of establishing
which database refactorings need to be
run against a specific database in
order to migrate it to a particular
build."
It is known to integrate with both Ant and Maven.
Try Liquibase.
Liquibase is an open source (Apache
2.0 Licensed), database-independent library for tracking, managing and
applying database changes. It is built
on a simple premise: All database
changes are stored in a human readable
yet trackable form and checked into
source control.
Supported features:
Extensibility
Merging changes from multiple developers
Code branches
Multiple Databases
Managing production data as well as various test datasets
Cluster-safe database upgrades
Automated updates or generation of SQL scripts that can be approved and
applied by a DBA
Update rollbacks
Database ”diff“s
Generating starting change logs from existing databases
Generating database change documentation
We use a piece of software called Liquibase for this. It's very flexible and you can set it up pretty much however you want it. We have it integrated with Maven so our database is always up to date.
You can also check Flyway (400 questions tagged on SOW) or mybatis (1049 questions tagged). To add to the comparison the other options mentioned: Liquibase (663 questions tagged) and DBDeploy (24 questions tagged).
Another resource that you can find useful is the feature comparison in the Flyway website (There are other related projects mentioned there).
You should take a look into OR Mapping libraries, e.g. Hibernate
Most ORM mappers have logic to do schema upgrades for you, I have successfully used Hibernate which gets at least the basic stuff right automatically.
At work we are trying to simplify an application that was coded with an overkill use of Spring Remoting. This is how it works today:
(Controllers) Spring MVC -> Spring Remoting -> Hibernate
Everything is deployed in a single machine, Spring Remoting is not needed (never will be needed) and adds complexity to code maintenance. We want it out.
How to ensure everything works after our changes? Today we have 0% code coverage! We thought on creating integration tests to our controllers so when we remove Spring Remoting they should behave exactly the same. We thought on using a mix of Spring Test framework in conjunction with DBUnit to bring up Oracle up to a known state every test cycle.
Has anyone tried a similar solution? What are the drawbacks? Would you suggest any better alternative?
It always depends on the ratio effort / benefit that you are willing to take. You can get an almost 100% code coverage if you are really diligent and thorough. But that might be overkill too, especially when it comes to maintaining those tests. But your idea is good. I've done this a couple of times before with medium applications. This is what you should do:
Be sure that you have a well known test data set in the database at the beginning of every test in the test suite (you mentioned that yourself)
Since you're using Hibernate, you might also try using HSQLDB as a substitute for Oracle. That way, your tests will run a lot faster.
Create lots of independent little test cases covering most of your most valued functionality. You can always allow yourself to have some minor bugs in some remote and unimportant corners of the application.
Make sure those test cases all run before the refactoring.
Make sure you have a reference system that will not be touched by the refactoring, in order to be able to add new test cases, in case you think of something only later
Start refactoring, and while refactoring run all relevant tests that could be broken by the current refactoring step. Run the complete test suite once a night using tools such as jenkins.
That should work. If your application is a web application, then I can only recommend selenium. It has a nice jenkins integration and you can create hundreds of test cases by just clicking through your application in the browser (those clicks are recorded and a Java/Groovy/other language test script is generated).
In our Spring MVC / Hibernate (using v3.4) web app we use an Oracle database for integration testing.
To ensure that our database is in a known state each time the test suites are run, we set the following property in our test suite's persistence.xml:
<property name="hibernate.hbm2ddl.auto" value="create"/>
This ensures that the db schema is created each time our tests are run based on the Hibernate annotations in our classes. To populate our database with a know data set, we added a file named import.sql to our classpath with the appropriate SQL inserts. If you have the above property set, Hibernate will run the statements in import.sql on your database after creating the schema.