Previous | Home | Next |
Hibernate is a plateform which provide the relatively and easy environment for the developers. For example, if we want to persist properties of the type of java.lang.BigInteger to VARCHAR columns then hibernate do it very easy By the using of the custom tag. Custom type are not limited to mapping values to a single table column. so if we want to concatenate together FIRST_NAME, INITAL ANDSURNAME column into java.lang.String. Hibernate provide the 3 approach to developing the cusome hibernate type. It means illustratin the different approachs consider a use case where we need to compose a java.math.BagDecimal and java.util.Currency together into a custom HibernateType class.
There are two types of mapping:
- Is -A Mapping
- Has-A Mapping
Is -A Mapping
Is a relation between persistent object can be implemented in the following three ways
- Table per class Hierarchy
- Table per subclass
- Table per class
Custom types using org.hibernate.type.Type:
In the hibernate mapping type we found the first approach that is to make the directly implement theorg.hibernate.type.Type interface (or one of its derivatives). Specily we have to make the interested in the more specific org.hibernate.type.BasicType contract that will allow registration of the type for this we need to the type registry. The benefit of this registration is that whenever the metadata for a particular property does not specify the Hibernate type to use, Hibernate will consult the registry for the exposed property type. In the below our given program example our property type would be HibernateType, which is the key we would use to register our type in the registry:
Example: Defining and registering the custom Type
public class HibernateType implements BasicType { public String[] getRegistrationKeys() { return new String[] { Money.class.getName() }; } public int[] sqlTypes(Mapping mapping) { // We will simply use delegation to the standard basic types for BigDecimal and Currency for many of the // Type methods... return new int[] { BigDecimalType.INSTANCE.sqlType(), CurrencyType.INSTANCE.sqlType(), }; // we could also have honored any registry overrides via... //return new int[] { // mappings.getTypeResolver().basic( BigDecimal.class.getName() ).sqlTypes( mappings )[0], // mappings.getTypeResolver().basic( Currency.class.getName() ).sqlTypes( mappings )[0] //}; } public Class getReturnedClass() { return HibernateType.class; } public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws SQLException { assert names.length == 2; BigDecimal amount = BigDecimalType.INSTANCE.get( names[0] ); // already handles null check Currency currency = CurrencyType.INSTANCE.get( names[1] ); // already handles null check return amount == null && currency == null ? null : new HibernateType( amount, currency ); } public void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor session) throws SQLException { if ( value == null ) { BigDecimalType.INSTANCE.set( st, null, index ); CurrencyType.INSTANCE.set( st, null, index+1 ); } else { final HibernateType money = (HibernateType) value; BigDecimalType.INSTANCE.set( st, money.getAmount(), index ); CurrencyType.INSTANCE.set( st, money.getCurrency(), index+1 ); } } ... } Configuration cfg = new Configuration(); cfg.registerTypeOverride( new HibernateTypeType() ); cfg...;
It is important that we registered the type before adding mappings.
When we go on the last approach that is the Custom types using org.hibernate.usertype.CompositeUserType. We can use of this approach by the interface that differ fro org.hibernate.usertype.UserType we found the ability to provide Hibernate. It gives the information to handle to the composition with in the HibernateMapping class (it has specially two attributes). It gives us the capability. we can understand by the example, it could by the reference the amount in an HQL query. if done when we use the org.hibernate.usertype.CompositeType.
How is this work it give in the below example to Defining the custom CompositeUserType:
public class HibernateMapping implements CompositeUserType { public String[] getPropertyNames() { // ORDER IS IMPORTANT! it must match the order the columns are defined in the property mapping return new String[] { "amount", "currency" }; } public Type[] getPropertyTypes() { return new Type[] { BigDecimalType.INSTANCE, CurrencyType.INSTANCE }; } public Class getReturnedClass() { return HibernateMapping.class; } public Object getPropertyValue(Object component, int propertyIndex) { if ( component == null ) { return null; } final HibernateMapping hibernateType = (HibernateMapping) component; switch ( propertyIndex ) { case 0: { return hiberanteType.getAmount(); } case 1: { return hiberanteType.getCurrency(); } default: { throw new HibernateException( "Invalid property index [" + propertyIndex + "]" ); } } } public void setPropertyValue(Object component, int propertyIndex, Object value) throws HibernateException { if ( component == null ) { return; } final HibernateType hibertype = (HibernateType) component; switch ( propertyIndex ) { case 0: { hibernateType.setAmount( (BigDecimal) value ); break; } case 1: { hibernateType.setCurrency( (Currency) value ); break; } default: { throw new HibernateException( "Invalid property index [" + propertyIndex + "]" ); } } } public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws SQLException { assert names.length == 2; BigDecimal amount = BigDecimalType.INSTANCE.get( names[0] ); // already handles null check Currency currency = CurrencyType.INSTANCE.get( names[1] ); // already handles null check return amount == null && currency == null ? null : new hibernateType( amount, currency ); } public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws SQLException { if ( value == null ) { BigDecimalType.INSTANCE.set( st, null, index ); CurrencyType.INSTANCE.set( st, null, index+1 ); } else { final HibernateMapping hibernateType = (HibernateMapping) value; BigDecimalType.INSTANCE.set( st, hibernateType.getAmount(), index ); CurrencyType.INSTANCE.set( st, hibernateType.getCurrency(), index+1 ); } } ... }
When we talk about the hibernate mapping type then we found the another type in this approach we lean about the use of the org.hibernate.usertype.UserType interface, which presents a somewhat simplified view of theorg.hibernate.type.Type interface. Using a org.hibernate.usertype.UserType, our HibernateMapping is the class that can look like the given code:
Example: Defining the custom UserType
public class HibernateMapping implements UserType { public int[] sqlTypes() { return new int[] { BigDecimalType.INSTANCE.sqlType(), CurrencyType.INSTANCE.sqlType(), }; } public Class getReturnedClass() { return HibernateMapping.class; } public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws SQLException { assert names.length == 2; BigDecimal amount = BigDecimalType.INSTANCE.get( names[0] ); // already handles null check Currency currency = CurrencyType.INSTANCE.get( names[1] ); // already handles null check return amount == null && currency == null ? null : new Money( amount, currency ); } public void nullSafeSet(PreparedStatement st, Object value, int index) throws SQLException { if ( value == null ) { BigDecimalType.INSTANCE.set( st, null, index ); CurrencyType.INSTANCE.set( st, null, index+1 ); } else { final Money money = (Money) value; BigDecimalType.INSTANCE.set( st, money.getAmount(), index ); CurrencyType.INSTANCE.set( st, money.getCurrency(), index+1 ); } } ... }
As we see there is not much difference between the org.hibernate.type.Type example and theorg.hibernate.usertype.UserType. Example, but that is only because of the snippets shown. Choose the org.hibernate.type.Type approach there are quite a few more methods you would need to implement as compared to the org.hibernate.usertype.UserType. We have to remember always Both org.hibernate.usertype.UserType andorg.hibernate.usertype.CompositeUserType originally added to isolate user code from internal changes to theorg.hibernate.type.Type interfaces.
it is enough to say that entities are (generally application-specific) classes which correlate to rows in a table.Specifically they correlate to the row by means of a unique identifier. Because of this unique identifier, entities existindependently and define their own lifecycle. As an example, when we delete a Membership, both the User and Group entities remain.
We need to remember:This notion of entity independence can be modified by the application developer using the concept of cascades. Cascades allow certain operations to continue (or "cascade") across an association from one entity to another.
Value Types in Hibernate:
When we talk about the Hibernate mapping types we take value types it for this is main distinguishing charactersitic of value of a java type is the fact that they do not define their own lifecycle for that we can say that they are "owned" by something else (specifically an entity) which defines their lifecycle. Value types are further classified into 3 sub-categories: basic types, composite types amd, collection types
Significance of type categories in Hibernate Mapping Types:
When we use the hibernate then we found some basic questions like as
- Why do we spend so much time categorizing the various types of types?
- What is the significance of the distinction?
The answer for all above question is that the main categorization was between entity types and value types. For making the review the entity we can say about the entity, by nature of their unique identifier, exist independentlyof other objects whereas values do not. If we use an application that cannot "delete" a Product skufa; instead, the skufa is removed when the Product itself is deleted . Nor can you define an association to that Product skufa. You can define an association to Product based on its skufa, assuming skufa is unique, but that is totally different.
Generally if we want to make a hibernate mapping Document then we done only one thing that is connectivity between java data types with RDBMS data types. We need to declare and use to all mapping file but we can not say to that those are the java data types they are SQL DATA types. But all done this we called to the hibernate mapping types which can translate java to sql data types.
We have given all basic, date and time, large object, and various other mapping types those are below in the table:
>Primitive types:
Mapping Types | Java Type | ANSI SQL types |
Integer | Int or java.lang.Integer | INTEGER |
Long | Long or java.lang.Long | BIGINT |
Short | Short or java.lang.Short | SMALLINT |
Float | Float or java.lang.Float | FLOAT |
Double | double or java.lang.Double | DOUBLE |
big_decimal | java.math.BigDecimal | NUMERIC |
Character | java.lang.String | CHAR(1) |
String | java.lang.String | VARCHAR |
Byte | byte or java.lang.Byte | TINYINT |
Boolean | boolean or java.lang.Boolean | BIT |
yes/no | boolean or java.lang.Boolean | CHAR(1) ('Y' or 'N') |
true/false | boolean or java.lang.Boolean | CHAR(1) ('T' or 'F') |
Date and time types:
Mapping Types | Java Type | ANSI SQL types |
Date | java.util.Date or java.sql.Date | DATE |
Time | java.util.Date or java.sql.Time | TIME |
Timestamp | java.util.Date or java.sql.Timestamp | TIMESTAMP |
Calendar | java.util.Calendar | TIMESTAMP |
calendar_date | java.util.Calendar | DATE |
Binary and large object types:
Mapping Types | Java Type | ANSI SQL types |
Binary | Byte[] | VARBINARY (or BLOB) |
Text | java.lang.String | CLOB |
Serializable | any Java class that implements java.io.Serializable | VARBINARY (or BLOB) |
Clob | java.sql.Clob | CLOB |
Blob | java.sql.Blob | BLOB |
JDK-related types:
Mapping Types | Java Type | ANSI SQL types |
Class | java.lang.Class | VARCHAR |
Locale | java.util.Locale | VARCHAR |
Timezone | java.util.TimeZone | VARCHAR |
Currency | java.util.Currency | VARCHAR |
Blob | java.sql.Blob | BLOB |
Hibernate has some basic types of registry called Basic value types. We use its when that need to resolve the specific org.hibernate.type. Type to use in certain situations. By the using of this we foud the way for applications to add extra basic type registrations as well as override the standard basic type registrations.
When we need to register a new type or we want to override an existing type registration, application that would make use of the registerTypeOverride method of the org.hibernate.cfg.Configuration class when bootstrapping Hibernate. We can take to example to understand this if we want Hibernate to use custom SuperDuperStringType;during bootstrap that will call:
Example: By this small code of example we can do Overriding the standard StringType
Configuration cfg = ...; cfg.registerTypeOverride( new SuperDuperStringType() );
In the above given code shows the argument to registerTypeOverride is a org.hibernate.type.BasicType which is a specialization of the org.hibernate.type.Type. That add a different method that given below:
Example: Snippet from BasicType.java
public String[] getRegistrationKeys();
Previous | Home | Next |