You have some Java-JPA code and you want to generate a SQL schema? Or you wonder how GenMyModel generates from UML to SQL? Read on this practical post to find out more.
Java-JPA to SQL ?
JPA annotations are very useful to introduce a new abstraction from SQL to Java. Defining and handling Java entities mapped to SQL entities becomes very easy because of the level of information embedded in your Java code. And what if this information was used to generate your SQL schema? I would be pretty sweet isn’t it?
Well you and me are not the first to think about it. Developers already addressed this issue and wrote a Maven plugin to deal with this. The idea is simple but very effective: your annotated Java code is compiled and executed. During code execution, your database schema is created from the JPA annotations embedded in your Java code, then the maven artifact exports the created schema in a file.
Use your JPA annotations with Maven
There are many artifacts that generate SQL schemas from annotated sources. In this article, we are dealing with Hibernate 3 maven plugin. Here is an example with version
2.2. Of course, you must have a maven Java-JPA project, here is part of the
pom.xml relative to the maven plugin inclusion:
<?xml version="1.0" encoding="UTF-8"?> <project ...> ... <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>hibernate3-maven-plugin</artifactId> <version>2.2</version> <configuration> <components> <component> <name>hbm2ddl</name> <implementation>jpaconfiguration</implementation> </component> </components> <componentProperties> <outputfilename>schema.ddl</outputfilename> <-- put here schema file name <format>true</format> </componentProperties> </configuration> <dependencies> <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>2.2.9</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>3.5.3-Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>3.5.3-Final</version> </dependency> </dependencies> </plugin> </plugins> </build> </project>
And obviously, you have to fill your
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0"> <persistence-unit name="_my_unit_name_Unit" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>...</class> -+ <class>...</class> | Put here your entity class definition <class>...</class> -+ ... <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:spring"/> <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/> <property name="hibernate.connection.username" value="_my_user_name_"/> <property name="hibernate.connection.password" value="_my_pass_"/> <property name="hibernate.hbm2ddl.auto" value="create-drop"/> </properties> </persistence-unit>
Finally, the only things to do is to call the maven plugin:
mvn compile hibernate3:hbm2ddl
And voilà, your SQL schema is generated. This is as simple as that.
Cool… And what about GenMyModel?
As you probably know, GenMyModel is shipped with a UML to SQL generator that takes UML classes for SQL generation. Unlike traditional UML to SQL approaches which directly translate class diagrams to SQL, GenMyModel uses JPA annotations in order to give your more freedom in your diagram design.
Traditional UML2SQL generators use a small subset of the class diagram as input model. Unfortunately, you often cannot use class inheritance of class abstraction because translating class inheritance in SQL is not an easy task. Consequently, the code generator becomes difficult to maintain and to understand.
In GenMyModel, we wanted to more flexibility for designing their class diagrams. Class abstraction and class inheritance had to be handled by the generator so it can break the classical constraints implied by a direct translation from UML to SQL. Obviously, we had to go to the drawing board and the first results were not very conclusive (you should have seen them… but folks, that was thinking/testing time). We went back to the drawing board once again when we reached the UML2SQL enlightenment. The solution was right under our noses, we only had to use the JPA to SQL schema generation. Think about it:
- UML to Java is a tamed code generation.
- You already know how to deal with inheritance.
- Abstract classes? Easy-peasy.
- UML associations give us all the information we need about cardinality.
Finally, this is the strategy we have chosen and without the last generation pass, we have a UML to Java-JPA code generator – two for the price of one – not bad ! The final generation flow is the following:
UML -> Java-JPA -> SQL
It looks like a simple yet effective MDE approach isn’t it? This generator is quickly accessible using right-click on your diagram, then
Direct Generation -> SQL (do not confuse it with the one available in the generator panel, this one does not use JPA as intermediate representation):
The counterpart to this solution is that we have to generate a fully compilable Java-JPA code. In addition, we still have to find the correct way to deal with interfaces. Perhaps you have a solution?
Any tips or plugins you use to generate your SQL schema from your code? Feel free to share your tricks with every one, any comment is welcome.