You can write a unit test to populate the database, using JPA and plain Java. This test would be called by Maven as part of the standard build lifecycle. As a result, you would get an fully initialized database, using Maven, JPA and Java as requested.
I want to manually execute the flush/population. Also, do you really consider molesting unit tests a better approach than using a servlet? – Tuukka Mustonen Mar 11 '10 at 11:50 Well, you wanted to be part of the Maven lifecycle, so I suggested this approach.
But if this requirement can be lifted, the unit test is definetly not what I'd recommend. You could do that with a Servlet as you suggest, of with a ServletContextListener if you want the DB to be automatically populated on application start. BTW, if you use a Servlet, remember to setup some sort of security to avoid random people to mess with your DB... – Olivier Croisier Mar 11 '10 at 12:47.
Depend on your db. It is better to have script to set up db.
I don't quite understand what you mean by this. JPA/bernate are supposed to be database agnostic. Yes, it depends on the products how to set them up and I have functional Spring configuration.
However, I don't know how to launch that configuration and execute a certain class/method using Maven tasks. My database is HSQLDB but it could be any. Can you give an example?
– Tuukka Mustonen Mar 11 '10 at 11:47.
The usual way to do this is to use a SQL script. Then you run a specific bash file that populate the db using your . Sql If you want to be able to programmatically set your DB during the WebApp StartUp you can use a Web Context Listener.
During the initialization of your webContext you can use a Servlet Context Listener to get access to your DAO (Service Layer.. whatever) create your entities and persist them as you use to do in your java code p.s. As a reference Servlet Life Cycle If you use Spring you should have a look at the Standard and Custom Events section of the Reference. That's a better way to implement a 'Spring Listener' that is aware of Spring's Context (in the case you need to retrieve your Services form it).
If yes, then I think this is the way to go.In order to prevent flush/population after each restart, I could first run the application with an additional variable passed to maven/JVM and use that variable as an indicator whether or not to do the actions. How would you automatically shut down the process after flush/population was executed? Use brute force to kill the process?
– Tuukka Mustonen Mar 11 '10 at 12:00 Yes, a variable passed in at startup should be fine. It's a listener that is used when the context is started, you don't need to kill any process. It's easier to access the bean defined in your spring context etc.Your Spring xml config should be ok when you reach ContextStartedEvent.. It's the 1st place I would put my logic to persist real entities using the Spring services.. it should be easy and fast to develop.. give it a try – mickthompson Mar 11 '10 at 12:59 Anyone addressed the problem mentioned here?
Why isn't Spring firing up a ContextStartedEvent when the context is started up? – Eugen May 9 at 8:26.
You could create JPA entities in a pure Java class and persist them. This class could be invoked by a servlet but also have a main method and be invoked on the command line, by maven (with the Exec Maven Plugin) or even wrapped as a Maven plugin. But you're final workflow is not clear (do you want the init to be part of the application startup or done during the build?) and requires some clarification.
Sorry for the delayed reply. I suppose I want the population to occur during the application startup (or during run by executing a servlet) in order to flexibily flush/populate the db. I took a glance at the Maven exec plugin, but I fear it cannot set up the Spring context.
Also, directly running the class doesn't set up Spring context either, so I guess I would need special code to programmatically set it up. – Tuukka Mustonen Mar 19 '10 at 7:08.
In the aforementioned ServletContextListener or in a common startup place put all the forthcoming code Define your data in an agreeable format - XML, JSON or even java serialization. Check whether the initial data exists (or a flag indicating a successful initial import) If it exists, skip. If it does not exist, get a new DAO (using WebApplicationContextUtils.
GetRequiredWebApplicationContext(). GetBean(..)) , iterate all predefined objects and persist them via the EntityManager in the database.
I'm not sure if you can get away from using some SQL. This would depend if your develoeprs are staring with an empty database with no schema defined or if the tables are there but they are empty. If you starting with empty tables then you could use a Java approach to generating the data.
I'm not that familiar with Maven but I assume you can create some task that would use your DAO classes to generate the data. You could probably even write it using a JVM based scripting language like Groovy that would be able to use your DAO classes directly. You would have a similar task that would clear the data from the tables.
Then your developers would just run these tasks on the command line or through their IDE as a manual step after checkout. If you have a fresh database instance that I think you will need to execute some SQL just to create the schema. You could technically do that with executing SQL calls with hibernate but that really doesn't seem worth it.
What you suggest is quite what I need. Having simple tasks re-initialize database would rock and that's actually what I am here after (I would like them to be Maven tasks, but sure, they could be any). However, I think it's still not clear for both of us how to accomplish this.
That was the core of the question. If you got any samples maybe you could share? By the way, we don't actually need any raw SQL/schema setup - bernate does that for us.
– Tuukka Mustonen Mar 19 '10 at 7:13.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.