Saturday, January 30, 2010

Generating EJB3 classes from a database

Generating EJB3 classes from a database is not that hard. Yay! First you need to download and unzip hibernate tools. You'll want to have the hibernate tools docs at hand. Next you need to grab a bunch of jars. Almost all the jars can be found in /plugins/org.hibernate.eclipse.x.x.x/lib/tools/hibernate-tools.jar . Then download ejb3-persistence.jar. Below are all the jars I collected. Don't worry about overkill, you're not going to include any of these jars in your distribution.

antlr-2.7.6.jar dom4j-1.6.1.jar hibernate3.jar jtidy-r8-20060801.jar asm-attrs.jar ehcache-1.2.3.jar jaas.jar log4j-1.2.15.jar asm.jar ejb3-persistence.jar javassist.jar lucene-core-2.2.0.jar bsh-2.0b1.jar freemarker.jar jboss-cache.jar oscache-2.1.jar c3p0-0.9.1.jar hibernate-annotations.jar jboss-common.jar postgresql-8.4-701.jdbc3.jar cglib-2.1.3.jar hibernate-commons-annotations.jar jboss-jmx.jar proxool-0.8.3.jar commons-collections-2.1.1.jar hibernate-entitymanager.jar jboss-system.jar swarmcache-1.0rc2.jar commons-logging-1.0.4.jar hibernate-search.jar jdbc2_0-stdext.jar concurrent-1.3.2.jar hibernate-tools.jar jgroups-2.2.8.jar connector.jar hibernate-validator.jar jta.jar

Now create your build.xml file:

<?xml version="1.0" encoding="UTF-8"?> <project name="my-proj" default="gen_hibernate" basedir="."> <property name="src" location="src" /> <property name="build" location="build" /> <property name="generated" location="generated" /> <path id="toolslib"> <fileset dir="${basedir}"> <include name="lib/*.jar"/> </fileset> </path> <taskdef name="hibernatetool" classname="org.hibernate.tool.ant.HibernateToolTask" classpathref="toolslib" /> <target name="gen_hibernate"> <hibernatetool> <jdbcconfiguration packagename="" configurationfile="hibernate.cfg.xml" detectManytoMany="true" detectOptimisticLock="true"> </jdbcconfiguration> <hbm2hbmxml destdir="${generated}" /> </hibernatetool> </target> <target name="gen_java" depends="gen_hibernate"> <hibernatetool destdir="${src}"> <annotationconfiguration configurationfile="hibernate.cfg.xml"> <fileset dir="${generated}"> <include name="**/*.hbm.xml"/> </fileset> </annotationconfiguration> <hbm2java jdk5="true" ejb3="true"/> </hibernatetool> </target> <target name="compile" depends="gen_java"> <mkdir dir="${build}/classes" /> <javac srcdir="${src}" destdir="${build}/classes" classpathref="toolslib" /> </target> <target name="jar" depends="compile"> <jar destfile="my-proj.jar" basedir="${build}/classes" /> </target> <target name="clean"> <delete dir="${build}" /> <delete dir="${src}" /> <delete dir="${generated}" /> </target> </project>

If you're using postgres your hibernate.cfg.xml file should look like:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" ""> <hibernate-configuration> <session-factory name="myproj"> <property name="hibernate.connection.driver_class">org.postgresql.Driver</property> <property name="hibernate.connection.url">jdbc:postgresql://your-url</property> <property name="hibernate.connection.username">your-username</property> <property name="hibernate.connection.password">your-password</property> <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property> </session-factory> </hibernate-configuration> </pre></blockquote>

run ant jar and you should be good to go!

Depending on how you're setup you should also consider running <hbm2cfgxml ejb3="true"> it creates a nice hibernate.cfg.xml file with all the classes and your DB connection info.

Tuesday, January 19, 2010

Dependency Injection Frameworks - A Rant

Uncle Bob has a great post on dependency injection frameworks. I'm so glad he wrote that article. There is precious little out there (maybe this is the only article) about why the DI frameworks suck and why DI is great. To be clear DI by hand works very well. And if all you need to do is DI, rolling it by hand is just as good as using a framework. In fact it wasn't until recently that I even saw a point to DI frameworks at all.

The only argument about DI frameworks that ever made much sense to me was that DI frameworks are great if you want to run your application with different configurations. But when do you want different configurations? Seriously when? For me, the only time I've wanted different configurations is for testing. Not unit or automated testing, but testing in the sense of I want to run the app and I don't want to hit prod.

But why do you need a framework to do that? Maybe you have a different main method. Or maybe you have a properties file. But if all you need are different configurations, a DI framework is an expensive price to pay.

What are the costs? Besides needing to learn a new framework, the DI frameworks are like a cancer. Once you start using them they invade and don't stop invading. You start @Autowiring and @Inject-ing and soon your whole app is cluttered with that crap. Not to mention the XML configs or Guice modules floating around. Maybe I'm doing it wrong, but why do I even want to invest the time to learn how to do it right? The benefits of using the frameworks seem so slim it's doesn't seem worth my time.

However, I did get convinced recently that using Spring DI was the correct choice for a web app I'm working on. Why? Because when Spring manages your objects it does some magic with transactions and sessions and it's all pretty convenient. I still hate it! And it feels wrong. And I believe you can get the magic without the DI. It's a question of how much do you want to fight against your framework. For my current project the answer was clear, not that much.

The only value I get out of using Spring's DI is the magic it does in the background. Their DI is total crap. If you don't need the magic, it's hard to understand why you need the framework.

Web Statistics