Generating SerialVersionUID in Netbeans 7

There are many reasons why you should generate a unique id for Serializable java objects.

  • making sure you serialize and deserialize objects with the same structure
  • serializable objects without a defined id have one generated. different JVMs use different algorithms to generate ids. if you marshall objects across different platforms, the ids may not match
  • changes to classes that break backward compatibility should declare a changed UID to insure errors are thrown by old code using those objects.
To name just a few. If you’re interested, there is a Java Object Serialization Specification.
If you use Netbeans 7, there is a plugin that will auto-generate SerialVersionUIDs. In Kenai, there is a  SerialVerionsUID Generator project that has an nbm plugin eu-easyedu-netbeans-svuid-1.9.7.nbm .  The link points to the Netbeans 7.0.1 version. There are earlier versions of the plugin available to download from the project as well, at the time of this posting.
Once the plugin is installed, when creating a class that implements Serializable, right-click in the edit window, select Insert Code… , then select:
  • add generated serialVersionUID or
  • add default serialVersionUID
The correct syntax is added to the class file code.

Dynamic Schema and Database Table Creation with Netbeans, Hibernate and EJB3

Overview

There are plenty of examples describing how to build applications from existing database content using various tools and techniques. The assumption in the examples is that either the developer must use a legacy database or that the application is being built from the perspective of data modeling with an existing database. Some examples include:

But what if you want to build the logical data model defining classes first and you don’t have a pre-built database? You want to define only the object model with attributes and operations that make sense for the application in terms of business requirements and not have to be concerned with database entities and the corresponding relationships. Also you need serialized objects that can be easily passed between servers and clients. This article describes a way to define the logical business model first and dynamically create the corresponding schema, database and scripts which can be used to manage the database. It also briefly covers using inheritance strategies which can be applied in the creation of a database.

This example was built with

  • Netbeans 6.5
  • Java 6

The project files are located at my open source Assimilator project site.

The Model

A simple model for  cycling teams is constructed in this example.  Represented are teams, team members and an inheritance structure for different types a bicycles that a team member may have. The UML class diagram for the logical object model looks like.

Cycling Teams Class Diagram

Cycling Teams Class Diagram

Each team has a set of members, each member is designated a specific type and each member can have a set of associated bicycles. Bicycle is an abstract base class and there are three concrete classes which extend Bicycle.

Defining the Database Connection

Create a new database for the cycling team information …

  1. In Netbeans, click on the Services tab,
  2. right-click on JavaDB and select Create Database…
  3. fill in the dialog with the following information (the database location will be in the default Netbeans install directories)
  4. click OK
Create Java DB

Create Java DB

  1. right-click on Databases
  2. select create Database connection
  3. fill in the dialog with the values defined using the user name and password assigned while creating the database
  4. add ‘create=true’ in the Additional Props field
  5. select OK which makes the Advanced settings visible
  6. enter CYCLING for the schema type
  7. select OK
Database Connection

Database Connection

The new connection should show up in the connection list.

Creating the Netbeans Project

Project Creation

A compressed file containing all the Netbeans project files is include with this post. Uncompress the file and open the project with Netbeans using File->Open Project and open the uncompress project file.

Alternatively you create a new project and add in the files from the included archive. To create a new projects

  1. select File->New Project…
  2. select Java category and Java Application Project type
  3. select the Next button
  4. enter CyclingTeam for the project
  5. define the directory location to store the project files
  6. deselect Create Main Class and Set as Main Project
  7. select the Finish Button

newproject

newjavaapp

Libraries

To compile and run the code Hibernate and JavaDB libraries need to be included in the project settings. These libraries are included with the sample project file.

  1. right-click on the project icon and select Properties
  2. select Libraries from in the Categories panel and
  3. select the Compile tab
  4. click the Add Jar/Folder… button and add all the jar files from the hibernate-support directory and the javaee.jar
  5. select relative path
  6. Click the Choose button
  7. add the same libraries under the Run Tests tab
  8. add the JUnit 4.5 library under the Compile Test tab
  9. click OK on the properties dialog box
Project Library Settings

Project Library Settings

Coding

Implementing the Business Model

All the code for this project is included in the project file. There are a few things to note about the source code. Following the logical model, first create the the CyclingTeams class. Creating this class using the Netbeans wizards is an easy way to be guided through the creation of persistence unit file.

  1. right-click the project CyclingTeams Source Package
  2. select new entity class
  3. enter CyclingTeam for the classname
  4. com.sample.cycling for the package name
  5. Long for the Primary key type
  6. click on the Create Persistence Unit button
  7. in the new dialog box enter CyclingTeamsPU for the Persistence Unit Name
  8. select Hibernate for the Persistence Provider
  9. on the Data Source pull-down menu select New Data Source
  10. enter CyclingTeams for the JNDI name
  11. select the CyclingTeams database connection
  12. click OK
  13. click Create
  14. click Finish

This example uses EJB3 annotations. Every class defined in this example corresponds to an entity so is tagged with the @Entity annotation at the beginning of the class definition. Also,  classes have an @Id annotation defined on the variable to be used as the database key value. In this example, the strategy for generating the value is Auto which is the default value.

In the CyclingTeam class, in addition to the code generated by the wizard, add the following code:

@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
    Collection<TeamMember> teamMembers;

    public Collection<TeamMember> getTeamMembers() {
        return teamMembers;
    }

    public void setTeamMembers(Collection<TeamMember> teamMembers) {
        this.teamMembers = teamMembers;

The class contains a Collection of TeamMembers. The OneToMany annotation defines a many-valued association with one-to-many multiplicity to be used in the database schema. The cascade type defines which  operations that must be cascaded to the target of the association. In this case, all operations. Fetch defines that the association must be eagerly fetched rather than the default lazily loaded. The corresponding getter and setter methods are defined. The TeamMember class also has a collection of Bicycles defined in the same way with annotations.

Notice that an @Id is defined in the Bicycle abstract base class but not in the other concrete bicycle classes. The key value only needs to be defined in the base class.

Note. At the time of writing, the Hibernate JPA persistence provider has some known issues that can cause problems. While not specific to NetBeans, these issues can be worked around by choosing eager as the association fetch value [@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER] and java.util.Set as the collection type. When using the Hibernate JPA persistence provider and choosing default or lazy as the association fetch value for mapping, an org.hibernate.LazyInitializationException exception can occur at runtime. If you choose an association fetch value of eager and you do not also choose java.util.Set as the collection type, an org.hibernate.HibernateException can occur (with the message “cannot simultaneously fetch multiple bags”) at runtime. These issues pertain to the Hibernate JPA persistence provider and not to the default persistence provider.

Persistence Unit

The persistence.xml file generated earlier needs to have all the entity classes added. Open the file which is in the Configuration Files folder.

  1. select the Design tab
  2. select Add Classes button
  3. select all the classes listed in the Add Entity Class dialog box
  4. select OK

To add the rest of the Hibernate properties, select the XML tab and copy in the properties listed below. The entire persistence.xml file contents should looks like the following:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" 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_1_0.xsd">
  <persistence-unit name="CyclingTeamPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>com.sample.cycling.Bicycle</class>
    <class>com.sample.cycling.CyclingTeam</class>
    <class>com.sample.cycling.RoadBicycle</class>
    <class>com.sample.cycling.TeamMember</class>
    <class>com.sample.cycling.TimeTrialBicycle</class>
    <class>com.sample.cycling.TrackBicycle</class>
    <properties>
      <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
      <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/>
      <property name="hibernate.show_sql" value="false"/>
      <property name="hibernate.sequence" value="cycling_teams_sequence"/>
      <property name="hibernate.connection.url" value="jdbc:derby://localhost:1527/CyclingTeams;create=true"/>
      <property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.ClientDriver"/>
      <property name="hibernate.connection.password" value="rocks"/>
      <property name="hibernate.connection.username" value="cycling"/>
      <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
    </properties>
  </persistence-unit>
</persistence>

JPA Controllers

A set of classes which control access to the entities, manage the database connections and provide the base logic for correctly mapping the relationships within the business classes can be  automatically generated.

  1. right-click the CyclingTeam-ejb project icon
  2. select New->Generated JPA Controller Classes from Entity Classes…
  3. select Add All to include all the entity classes
  4. select Next
  5. set the package name to com.sample.cycling.jpacontrollers
  6. select Finish

Controllers define the JPA access through create, edit, destroy, and find methods. The controllers define the entity managers to use and manage the transactions. There are controllers for each entity type. Each controller manages the associations between entities as well. For example, if a CyclingTeam has a collection of associated TeamMembers  and the CyclingTeam is deleted from the database, the association references in the database are also cleaned up.

Additional code may need to be added to the controllers to help manage the objects in the model. Im this example a check for null Collection fields is added to the default generated code. In CyclingTeamJpaController the follwoing code was added to the create method

if (cyclingTeam.getTeamMembers() == null) {
            cyclingTeam.setTeamMembers(new HashSet<TeamMember>());
 }

Similar code is added to the create method in TeamMember to check for a null Bicycles collection.

Testing

Creating unit test is a useful way to exercise the code to understand how it works and to identify errors.

  1. right-click on the CyclingTeamJpaCopntroller class
  2. select Tools -> Create JUnit Tests…
  3. use the default settings making sure the Location is set to  Test Packages
  4. click ok

A default unit test class is created with code generated to exercise all the methods in the CyclingTeamJpaController class. By default all the test are set to fail. They must be edited to perform the desired tests. The project file included with this post has a few edited unit test classes. The tests provide a start to understand how the JPAControllers can be called by web services or EJBs.

To run the unit test, right-click in the edit window of the class and select Run File.  The unit test causes the database schema to be created and test records to be inserted, read and edited.

To view the contents in the database, comment out the code in the teardown method of the CyclingTeamJpaController class and run the tests. Select the Services tab and open the jdbc connection for CyclingTeams. Right click on the Tables node and select Refresh. The tables created in the database should now be visible. Right-click on the CYCLINGTEAM table and select View Data. This will subit an SQL query to show all the records in the table.

Creating DDL

Using the hibernate tools, ddl sql scripting can be generated to create all the tables and relationships for the business model and to clean up the database with drop statement for all the generated tables. In the project build.xml file that is located in the top level directory of the project, add the following script to the end of the file.

<target name="-post-jar">
        <path id="hibernate.tools.lib">
            <pathelement path="${file.reference.antlr-2.7.6.jar}"/>
            <pathelement path="${file.reference.asm-attrs.jar}"/>
            <pathelement path="${file.reference.asm.jar}"/>
            <pathelement path="${file.reference.cglib-2.1.3.jar}"/>
            <pathelement path="${file.reference.commons-collections-2.1.1.jar}"/>
            <pathelement path="${file.reference.commons-logging-1.1.jar}"/>
            <pathelement path="${file.reference.dom4j-1.6.1.jar}"/>
            <pathelement path="${file.reference.ehcache-1.2.3.jar}"/>
            <pathelement path="${file.reference.hibernate-annotations.jar}"/>
            <pathelement path="${file.reference.hibernate-commons-annotations.jar}"/>
            <pathelement path="${file.reference.hibernate-entitymanager.jar}"/>
            <pathelement path="${file.reference.hibernate-tools.jar}"/>
            <pathelement path="${file.reference.hibernate3.jar}"/>
            <pathelement path="${file.reference.javassist.jar}"/>
            <pathelement path="${file.reference.jdbc2_0-stdext.jar}"/>
            <pathelement path="${file.reference.jta.jar}"/>
            <pathelement path="${file.reference.javaee.jar}"/>
            <pathelement path="${file.reference.freemarker.jar}"/>
            <pathelement path="${dist.jar}"/>
        </path>

        <taskdef name="hibernatetool" classname="org.hibernate.tool.ant.HibernateToolTask" classpathref="hibernate.tools.lib" />
        <hibernatetool destdir="${dist.dir}">
            <jpaconfiguration persistenceunit="CyclingTeamPU"/>
            <classpath>
                <path location="${dist.jar}"/>
            </classpath>

            <!-- Create SQL script -->
            <hbm2ddl outputfilename="cycling_teams_create.sql" export="false" format="true"/>

            <!-- Drop SQL script -->
            <hbm2ddl outputfilename="cycling_teams_drop.sql" export="false" create="false" drop="true" format="true"/>
        </hibernatetool>

    </target>

The target is executed after the project jar file is successfully created. Two scripts are generated in the ./dist directory.

cycling_teams_create.sql to create the tables,

cycling_teams_drop.sql to cleanup the tables.

These scripts are generated each time a Clean and Build is run on the project.

Summary

Projects requiring storing data in a database can be developed by creating the data model and database first and coding to the structure, or in this example a business object model can be created first and used to automatically generate the schema and database tables. Team skills and familiarity with various tools tend to dictate which approach is used.

For new projects, if you use the method described in this example, you’ll  see how development can rapidly cycle through business object model development and directly map changes to a database. Many development cycles can be done to accomodate rapid changes until the model and database structure have been normalized. The result should be a coherent object model easy to develop with serilaized objects easy to pass around  and a direct mapping to a database taking advantage of the Hibernate and EJB3 tools to help manage the data for you.