Visual Paradigm's ORM code generation has high flexibility. One example is to let users to define their own data type to handle meaningful data conversion in type level. There are two ways for type definition, which involve extending type classes with <<ORM User Type>> and <<ORM Parameterized Type>> stereotypes. In this article, we will go through the two ways of defining and implementing user-defined types.
ORM User TypeClasses extending the <<ORM User Type>> stereotype represent an ORM User Type class, which can be used for creating enumerated data type. Let's start from modeling. - In a Class Diagram, select ORM-User-Type Class from the diagram toolbar.
 - Click on diagram to create a ORM User Type class, and give it a name.
 - Create an ORM Persistable Class which uses the type class. Select ORM-Persistable Class from the diagram toolbar first.
 - Click on the diagram to create an ORM-Persistable class. The attribute conduct is set to be in Grade type.
 - We can show the association between the Student and Grade class by right-clicking on the Student class and selecting Show Association from the popup menu. This step is optional but can may make the model more expressive.

Here is the resulting Class Diagram.
 - In order to generate database, we need to synchronize the Class Diagram to Entity Relationship Diagram. To synchronize, right click on Class Diagram background and select Synchronize to Entity Relationship Diagram from popup menu.

An ERD is formed:
 - This ends modeling. To generate code and/or database, select Tools > Object-Relational Mapping (ORM) > Generate Code... from the main menu, and confirm the code generation dialog box.
 - ORM code is generated. Let's proceed with implementation. Below we are going to use Eclipse, an Java IDE, to show how to implement the generated code. There are two classes that we need to code, one is the type class itself, another one is the UserType class.
 - Let's take a look at the Grade class first. The class is empty as shown below.

Now, we need to fill out this class. Below is the final code content. Note that the three enumeration literal GOOD, FAIR and POOR are established.
/** * Licensee: Demo * License Type: Purchased */ package school;
import java.util.HashMap; import java.util.Map;
public class Grade { private String grade; public static final Grade GOOD = new Grade("Good"); public static final Grade FAIR = new Grade("Fair"); public static final Grade POOR = new Grade("Poor"); private static final Map INSTANCES = new HashMap(); static { INSTANCES.put(GOOD.toString(), GOOD); INSTANCES.put(FAIR.toString(), FAIR); INSTANCES.put(POOR.toString(), POOR); } private Grade(String grade){ this.grade = grade; } public String toString(){ return grade; } private Object readResolve(){ return getInstance(grade); } public static Grade getInstance(String grade){ return (Grade)INSTANCES.get(grade); } } //ORM Hash:5ac339c6012b2d1d261fffd8082db9 |
- Here comes the GradeUserTpe class. Some operations were generated. We just need to fill them in appropriately.

Below is the final code content:
/** * Licensee: Demo * License Type: Purchased */ package school;
import org.hibernate.usertype.UserType; import org.hibernate.*; import java.sql.*; import java.io.*;
public class GradeUserType implements UserType { private static final int[] SQL_TYPES = {Types.VARCHAR}; public int[] sqlTypes() { return SQL_TYPES; } public Object nullSafeGet(ResultSet aResultSet, String[] aStrings, Object aObject) throws HibernateException, SQLException { String grade = aResultSet.getString(aStrings[0]); return aResultSet.wasNull() ? null : Grade.getInstance(grade); } public void nullSafeSet(PreparedStatement aPreparedStatement, Object aObject, int aint) throws HibernateException, SQLException { if (aObject == null){ aPreparedStatement.setNull(aint, Types.VARCHAR); }else{ aPreparedStatement.setString(aint, aObject.toString()); } } public Object deepCopy(Object aObject) throws HibernateException { return aObject; } public boolean isMutable() { return false; } public Serializable disassemble(Object aObject) throws HibernateException { //TODO: Implement Method throw new UnsupportedOperationException(); } public Object assemble(Serializable aSerializable, Object aObject) throws HibernateException { //TODO: Implement Method throw new UnsupportedOperationException(); } public Class returnedClass() { //TODO: Implement Method throw new UnsupportedOperationException(); } public int hashCode(Object aObject) throws HibernateException { return aObject.hashCode(); } public boolean equals(Object aObject, Object aObject2) throws HibernateException { return aObject == aObject2; } public Object replace(Object aObject, Object aObject2, Object aObject3) throws HibernateException { //TODO: Implement Method throw new UnsupportedOperationException(); } } //ORM Hash:230dea99b2f90db3b5e90456231c24fd |
- Let's test the code with the generated sample. When invoking the setConduct method, we need to pass an object in Grade type, which are the three possible enumerated values GOOD, FAIR, POOR as coded above.

By executing the test code, a row of Student record will be created. We can see the underlying string value “Good” is stored in database when using the Grade object in code.

Code and project sample for ORM User Type can be downloaded at: http://files4.visual-paradigm.com/res/orm/SchoolExample.zip ORM Parameterized Type<<ORM Parameterized Type>> can reduce a lot of copy and paste by passing parameter when initializing your “type”. For example, you can limit the length of String values that store into database. - Same as the previous section, let's start from modeling. Create an ORM Persistable class with several attributes. Here is a Result class with three attributes. One for each subject.
 - Create the ORM Parameterized Type class by selecting ORM-Parameterized-Type Class from the diagram toolbar.
 - Click on the diagram to create.
 - Right click on the parameterized typed class and select Open Specification from the popup menu to open the specification dialog box.
- Open the ORM Parameterized Type tab in the dialog box.
- Specify the base type, which represent the base primitive type that we will deal with. In this example, DoubleType is used as we will deal with the examination result, which is a double typed value.
 - Add a Typedef by pressing the Add button near the bottom of the dialog box. Give a meaningful name for the Typedef to represent a rule. In this example, “From zero to hundred” is used to represent a rule that enforce the double value must be within 0 to 100.
 - Double click on the Typedef row or click Edit... to enter the Edit Typedef dialog box. Click Add to add parameters which will be used to determine whether the value is correct or not. In this example, min and max are used. However, it is perfectly alright to use whatever name you like.
 - Confirm the changes and go back to the diagram.
- Now we need to link up an attribute with a Typedef, which means to enforce an attribute to follow a defined rule. Right click on an attribute and select Open Specification... from the popup menu.
 - In the ORM Attribute Detail tab, select the appropriate ORM parameterized type. In this case, From zero to hundred is selected.
 - Generate ORM code.
- Here comes the implementation. We need to implement the logic of the rules by making use of the parameters. Open the source of the type class. In this case, open ResultParamType.
 - Here is how the source code originally looked like:

The method setParameterValues passes in the parameter and the required value. We need to extract the value and store it globally. Then, we shall override the set method for implementing the logic of checking the correctness of value, and returning the value to store into database. Below is the final code content. The setParameterValues method reads and store the expected value for min and max parameter. Then the set method evaluates the Object argument, which is actually the wrapper type for primitive type, then check against the expected min and max values, and finally return back the correct value for being stored in database./** * Licensee: Demo * License Type: Purchased */ package exam;
import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.*; import org.hibernate.type.*; import org.hibernate.usertype.*;
public class ResultParamType extends DoubleType implements ParameterizedType { private Integer min; private Integer max; public void setParameterValues(Properties properties) { String min = properties.getProperty("min"); String max = properties.getProperty("max"); if (min != null){ try{ this.min = Integer.valueOf(min); }catch(Exception e){} } if (max != null){ try{ this.max = Integer.valueOf(max); }catch(Exception e){} } } @Override public void set(PreparedStatement arg0, Object arg1, int arg2) throws SQLException { Double lValue = (Double) arg1; if (min != null){ lValue = new Double(Math.max(lValue.doubleValue(), min.doubleValue())); } if (max != null){ lValue = new Double(Math.min(lValue.doubleValue(), max.doubleValue())); } super.set(arg0, lValue, arg2); } } //ORM Hash:18de9bc098ef0c7c0a61d275ba7e9f43 |
- Let's test the code by running the following sample:
 - This is the result obtained by executing the test code. The value 90 remain unchanged, while the value 101 is corrected to 100, resulted by the set method implemented in ResultParamType.

Code and project sample for ORM Parameterized Type can be found at: http://files4.visual-paradigm.com/res/orm/ExaminationlExample.zip
 |