As seen in an earlier post, Composite Identifiers are used when you have natural primary keys as opposed to surrogate keys.In this case the primary keys are assigned by the user. There exists the case when the primary key used is actually the primary key of some other table. i.e. it is a foreign key. In this case how do we manage the identifier and also create an association for directional navigation ??
Search This Blog
Friday, 30 December 2011
Composite Identifiers And Associations-1
Sunday, 25 December 2011
Using a Map with the formula attribute
In different posts I have worked with different data in collections - with java data type (Strings), components and then with entities. For maps the technique was based on having a value that became the map key and the value was the data as String or a Component or the Entities. This meant that there were two columns - one holding the key and the other representing the value.
Friday, 23 December 2011
Creating a Ternary Relation -2
In the absence of any extra information, a map can be used to represent a ternary relationship. Considering the same example of People, chocolates and the Shops selling them. The relation could be maintained as a map:
class Person {
Map<Shop, Chocolate> shopChocolate;
}
I had to get rid of the additional join columns from the previous example. The detailed example would involve the same entities as last time.Monday, 19 December 2011
Creating a Ternary Relation -1
In the previous post we saw how to manage a many to many relation with join data. The same concept can be extended further to create a simple ternary relation. In the earlier example the "shopName" attribute of the join table was a simple String. This could be changed to a Shop Entity instead.
Sunday, 18 December 2011
Adding columns to the join table
Previously we created a many to many relation between People and the chocolates they liked. This resulted in a "many people like many chocolates" relation. The relation data was mapped to a separate join table. Now we would like to hold some additional information such as date a person first tasted the chocolate and shop name from where the chocolate was eaten. (I know the example gets weirder and weirder but what the heck, I want to try this example out.)
This now means that the join table will have to hold information additional to the association details.
This now means that the join table will have to hold information additional to the association details.
Monday, 12 December 2011
Creating a many to many association - BiDirectional
Continuing from the last post, I shall now make the Person Chocolate relation bidirectional. This means that chocolate will also hold a collection of its fans. Instead of using a set here, I decided to use a bag. The updated java files are as below:
Creating a many to many association - UniDirectional
After one to many, its time to try a many-to-many association. This association is rarely used , instead being replaced with 2 many-to-one associations. For this example I decided to create two entities- people and chocolate (ya am still on chocolates only :) ). Many people like mannnnnnnnnnnnnnnny chocolates. As we are considering unidirectional relation, the mapping can be seen from the People class only.
Tuesday, 6 December 2011
One To Many association that is optional
We have seen one to many relations before but Hibernate also supports an optional one to many relationship. Consider chocolates and Bags. There is a possibility that some chocolates exists outside of a bag. Every chocolate can at any given time be in one and only one bag. However a particular chocolate may also not be in any bag. This makes the one to many relation an optional association.
Sunday, 4 December 2011
One to One Association Using Foreign Key
In the earlier technique I mapped a one-to-one relation using a shared primary key. Now I shall attempt to create the same relation-ship using foreign keys.
Both the tables in this case will have their own independent primary key and id generation strategies. One of the tables (mostly the entity owning the relation, in this case the Order_Data) has a column which references the primary key from the other table.
Both the tables in this case will have their own independent primary key and id generation strategies. One of the tables (mostly the entity owning the relation, in this case the Order_Data) has a column which references the primary key from the other table.
Friday, 2 December 2011
One to one association that is optional
In previous posts I have tried out one to one associations involving shared primary keys and foreign keys.In the that example an Order had a one to one relation between BillDetail.Consider the scenario wherein an Order is created separately from the BillDetail. The Bill Detail information is added at a later date. This means that the one-to-one relation between the two entities is optional and may not be always present.The relation would require that
Wednesday, 30 November 2011
One To One Association Using Shared Primary Keys
Consider the example of an Order. The Order includes various details such as items brought, billing information, mode of payment, delivery address etc.
One way to represent all these information is to have a single order table and then implement the different data as components. This would be great from the point of performance and ease of management.
However there may be cases wherein the data may be needed in separate tables.For example the Accounts module might need reference to the Billing Information. The Shipping module might need information related to the delivery address and so on.
The point is that we may be needed to implement these as individual entities with one-to-one relations among them. For example
One way to represent all these information is to have a single order table and then implement the different data as components. This would be great from the point of performance and ease of management.
However there may be cases wherein the data may be needed in separate tables.For example the Accounts module might need reference to the Billing Information. The Shipping module might need information related to the delivery address and so on.
The point is that we may be needed to implement these as individual entities with one-to-one relations among them. For example
Monday, 28 November 2011
Collections and The Inverse Attribute
In a previous post I successfully created a bidirectional relationship between Shelf and Books. We also saw that hibernate treats these as two individual unidirectional relationships in the application.
Saturday, 26 November 2011
cascade = "delete-orphan"
In an earlier post we have seen the various settings supported by cascade property. In a parent-child relationship we are provided with three different type of cascades:
- save-update
- delete
- delete-orphan
Thursday, 24 November 2011
Bi Directional Associations
In earlier posts I created associations between Parent and Entity from both sides in an unidirectional manner. Either I created a reference to parent from within the child element or I added a set of children inside parent.
Here I shall use a bidirectional relationship.
Here I shall use a bidirectional relationship.
Tuesday, 15 November 2011
Simplest UniDirectional Association in Hibernate
I decided to implement an unidirectional many-to-one association.
A Shelf contains many books. Each book can exist on only one shelf. No book can exist without being assigned a shelf.
The above would be represented in database by two tables - Shelf and a Book.
A Shelf contains many books. Each book can exist on only one shelf. No book can exist without being assigned a shelf.
The above would be represented in database by two tables - Shelf and a Book.
Uni Directional Collections
In this example I created the relation between shelf and book and set the direction of relation from Book to Shelf. i.e. the Book is aware of the shelf. Which is the same case as the db schema. The foreign key is in the Book table and not vice-versa.
Saturday, 12 November 2011
Collections: Entities vs Values
We have seen that Hibernate supports both collection of Entities and collection of values / components. Here is a short summary of the points of note when working with the two.
Wednesday, 9 November 2011
Creating A Custom Id Generator
We have already seen the different identifier generators supported by Hibernate. However this does not constrain us to use these generators only. Hibernate very magnanimously allows us to create our own custom generator.
Sunday, 6 November 2011
Deleting from Collections
In the previous examples I created and used collections that represented simple value elements or components. However one thing that I wanted to try is deleting from collections. Removing the value from the collection for a session bound
Thursday, 3 November 2011
Collections of Components
Earlier I created varied collections using the Java String class. In this example I will replace that with a Component class.
public class Chocolate { private String name; private String brand;
Sunday, 30 October 2011
Component of Components
Hibernate allows us to compose our components out of other components. This is making extreme use of java in the SQL world, but provides us with a great deal of flexibility. I modified the address class in the previous example to be composed of components.
Friday, 28 October 2011
Ordered Collection
In an earlier post we saw that hibernate provides us with the option to use Sorted Collections. In these collections the objects were fetched form the database and inserted into collections in a sorted order. Thus the sorting of elements happened in the Java Domain. This was an example of in-memory sorting.
Hibernate also provides an alternative to the above technique called ordered collections.
Hibernate also provides an alternative to the above technique called ordered collections.
Friday, 21 October 2011
Hibernate Collections - The whole variety -2
In the last post we saw a java class that included the different collections supported in Hibernate and the mapping file. If we were to start the server with the hibernate set to DDL creation then the logs are as below:
Exception in thread "main" org.hibernate.InvalidMappingException:
Saturday, 15 October 2011
Hibernate Collections - The whole variety -1
In the previous post we saw the varied collections available for use in Hibernate. I created a class which includes the different collection types.
public class Person { private Long id; private String name;
Wednesday, 12 October 2011
Hibernate And Collections Support
Hibernate supports the use of Collections in the Java model objects. Associations between tables are represented using these collections.
e.g.: If there is a one-to-many relation between owner and pet (1 Owner has many pets) then a collection of pets can be mapped in the Owner class.
e.g.: If there is a one-to-many relation between owner and pet (1 Owner has many pets) then a collection of pets can be mapped in the Owner class.
class Owner { private List<Pet> pets = new ArrayList<Pet>(); }
Sunday, 9 October 2011
The Hibernate Inheritance Mechanism - 3 + 4
We saw in approach 3 that a single table is used to represent an entire hierarchy. The end result was a table with sets of unrelated columns, absence of nullability constraints and constantly changing column count on addition of new sub-classes.
In approach 4 we saw how the 3 class hierarchy was split into 3 tables with each class being given a table. Although the resultant schema was a highly normalized schema, it required joins for fetching records of any of the concrete class and was slightly more complex to implement compared to earlier approaches.
Here we shall modify approach 3 to use approach 4 techniques to come up with a slightly more cleaner implementation for approach 3.
In approach 4 we saw how the 3 class hierarchy was split into 3 tables with each class being given a table. Although the resultant schema was a highly normalized schema, it required joins for fetching records of any of the concrete class and was slightly more complex to implement compared to earlier approaches.
Here we shall modify approach 3 to use approach 4 techniques to come up with a slightly more cleaner implementation for approach 3.
Thursday, 6 October 2011
The Hibernate Inheritance Mechanism - 4
We have seen three of the inheritance techniques as of yet.This is the fourth in the series.
Table per subclass
In this technique a table is created for every class in the hierarchy. There exists a separate table for every interface/abstract class/concrete class that has any persistent properties.
Table per subclass
In this technique a table is created for every class in the hierarchy. There exists a separate table for every interface/abstract class/concrete class that has any persistent properties.
<?xml version="1.0"?>
Monday, 3 October 2011
The Hibernate Inheritance Mechanism - 3
Table per Class Hierarchy:
In this technique an entire class hierarchy is mapped to a single table. Both the Footballer and Cricketer Information will be saved as different rows in the same table.To distinguish the data in each row a discriminator is added.
In this technique an entire class hierarchy is mapped to a single table. Both the Footballer and Cricketer Information will be saved as different rows in the same table.To distinguish the data in each row a discriminator is added.
Saturday, 1 October 2011
The Hibernate Inheritance Mechanism - 2
Table Per Concrete Class + Unions
Continuing with the inheritance mechanisms, I shall now attempt to implement the second approach. This approach tries to overcome the drawbacks of the first technique.
In this technique
Continuing with the inheritance mechanisms, I shall now attempt to implement the second approach. This approach tries to overcome the drawbacks of the first technique.
In this technique
- The abstract class is also mapped into Hibernate.
Wednesday, 28 September 2011
The Hibernate Inheritance Mechanism - 1
Table per Concrete Class + Implicit Polymorphism
This is the technique with minimum development efforts. The technique follows the below simple steps:
This is the technique with minimum development efforts. The technique follows the below simple steps:
- For each concrete class, one table is created.
- All the inherited properties are mapped in each of these tables.
- The abstract (base) class is not represented in SQL
Tuesday, 27 September 2011
The Hibernate Inheritance Mechanism - Preview
Inheritance which is one of the pillars of Object Oriented Programming Model isn't a big player in the SQL environment. While Objects can form both IS-A and HAS-A relationships, Tables are only aware of HAS-A relationships. (for e.g. 1 Person has many Vehicles)
Hibernate provides techniques that allows us to represents Tables via inheritance relationships. Hibernate has 4 different approaches:
Hibernate provides techniques that allows us to represents Tables via inheritance relationships. Hibernate has 4 different approaches:
Saturday, 24 September 2011
Composite Identifiers
In the previous discussions of identifiers the focus was on implementing surrogate keys as means to uniquely identify the records.
The wikipedia definition of surrogate key states that
"A surrogate key in a database is a unique identifier for either an entity in the modeled world or an object in the database. The surrogate key is not derived from application data."
The wikipedia definition of surrogate key states that
"A surrogate key in a database is a unique identifier for either an entity in the modeled world or an object in the database. The surrogate key is not derived from application data."
Wednesday, 21 September 2011
Bidirectional Components
Components in Hibernate can include a back-reference that allows them to link back to their owning Entity. I decided to try this out and for this created a simple Person entity that includes a name and an Address.
Tuesday, 20 September 2011
Creating a Hibernate Custom Type - 4
Let us look at the EnhancedUserType.This interface extends the UserType interface and provides additional methods to allow usage in XML representation. I shall implement a type that will allow saving of Enums directly to the database.
Friday, 16 September 2011
Creating a Hibernate Custom Type - 3
In the previous articles we saw how to create Custom Mapping Types - both implementations of UserType and CompositeUserType. There is the possibility wherein we may need to add some configuration values to our custom types.
Wednesday, 14 September 2011
Creating a Hibernate Custom Type - 2
As seen in the previous blog, the UserType interface does not provide the ability to use the properties of the new Type in Hibernate Queries. For this we need to implement the more powerful CompositeUserType.
Using the same AuditData object from the previous example,
Using the same AuditData object from the previous example,
Monday, 12 September 2011
Creating a Hibernate Custom Type - 1
As seen before Hibernate comes with a huge collection of mapping types. These cover a very wide range of types from single bit fields to blobs and clobs.
It is also possible that we would like to retrieve the data in one of our own pre-defined formats. Hibernate supports this by allowing us to define our own customized mapping types.
It is also possible that we would like to retrieve the data in one of our own pre-defined formats. Hibernate supports this by allowing us to define our own customized mapping types.
The Hibernate Types
Hibernate as we know provides the technique to convert the sql data to java objects . In case of XML mappings, hibernate includes a type attribute to indicate the conversion mechanism to be used.
Id Generators - 6
I shall finish my series on generators with the uuid.hex type. Both uuid.hex and uuid refer to the same generator. The uuid generator uses a 128-bit UUID algorithm to generate identifiers of type string, unique within a network (the IP address is used).
Id Generators - 5
I shall cover the select and assigned generators in this article.
select:
This is used when the primary key is to be generated by some database logic. For e.g. the primary key is assigned by a database trigger. As hibernate did not assign the primary key (and it is not a generated value like auto-increment) how does it set the object's id ?Sunday, 11 September 2011
Id Generators - 4
I shall cover the foreign and guid classes of generators in this post.
The foreign generator is used with objects that do not have their own key assigned to them.These use the identifier of another associated object. They are generally used along with <one-to-one> primary key association.
Foreign:
The foreign generator is used with objects that do not have their own key assigned to them.These use the identifier of another associated object. They are generally used along with <one-to-one> primary key association.
Id Generators - 3
Let us look at at the native and increment types in this post.
native
Consider the simple POJO person that represents a Person tableId Generators - 2
Continuing from the previous post, we shall look into hilo and seqhilo generator types.
hilo
The hilo algorithm, as per the hibernate documentation, is one of the most popular id generation algorithms available.The working involves creating a separate table in the database that is used to help in the key generation. (An alternative approach is available which works on Oracle styled sequences too)Id Generators - 1
Most tables we create in the database have primary keys. The mapping classes that we create in java include the <id> or <composite-id> attribute to map the primary key.
In case of the <id> attribute, hibernate provides an optional <generator> element that is used to manage the creation of id values for new records inserted in tables. The generator class actually includes a class attribute which specifies the class (and therefore the technique) used to generate primary keys.
In case of the <id> attribute, hibernate provides an optional <generator> element that is used to manage the creation of id values for new records inserted in tables. The generator class actually includes a class attribute which specifies the class (and therefore the technique) used to generate primary keys.
Saturday, 10 September 2011
Dealing with common content in mapping files
In the previous post we looked into component mapping. I created a component for audit fields and added it to my Java POJO class. Everything worked fine, until I observed that the same mapping is done in the scores of other database tables that we create in our application. The same fields are repeatedly added in our java models. The same mappings are created in our hbm files. The process gets repeated continuously.
Creating Components in Hibernate
The Java POJOs that we create need not be composed solely of Primitive types. It is possible to group together value fields into Java classes. Such objects which exist as member fields inside the mapped java classes are called components.
Components are classes (or columns in the table) that do not have their own life-cycle.
Components are classes (or columns in the table) that do not have their own life-cycle.
The mapping with minimum details
The mapping files are used to map the database table to the java object. For every such class, all the persistent properties have to be mapped. This is true in case of annotations too.
All Mapped classes must declare the primary key column of the database table. The
All Mapped classes must declare the primary key column of the database table. The
<id>
element defines the mapping from that property to the primary key column.
Using Derived properties
Hibernate provides us with the ability to include properties that do not map to any column in the database. These are fields that are calculated based on formula applied on other columns/other tables/ SQL functions/ custom procedures etc.
The function is evaluated every time the entity is retrieved from the database. Consider the case where we have a person whose date of birth is saved in the database. Then the age of this person can be represented in the domain object as a derived property
Thursday, 8 September 2011
Enforcing the Rules for naming conventions
There is often a need to enforce strict naming conventions for the database just as we have naming conventions in java. As multiple developers work on different tables in the schema, there is a possibility of each developer following his own naming conventions. To avoid this Hibernate provides us with the NamingStrategy interface, that can be used to enforce naming standards automatically.
The solution requires us to implement our own naming strategy or use several of the provided options.
The solution requires us to implement our own naming strategy or use several of the provided options.
Save only those that need saving
When the application is started Hibernate will generate CRUD statements for all the mapped tables. For example, if consider the pet table (I have maintained the audit columns added in the previous post.) then from the logs we can see the following:
3719 [main] DEBUG org.hibernate.persister.entity.AbstractEntityPersister - Stat
ic SQL for entity: com.menagerie.domain.entity.Pet
3719 [main] DEBUG org.hibernate.persister.entity.AbstractEntityPersister - Ver
sion select: select ID from PET where ID =?
Using db generated values
There are scenarios when certain fields in the table can be managed by the database. In such cases we do not need Hibernate to update these fields from the model. One such scenario could be the audit fields.
Most tables that we create include properties to manage the audit details. Typical columns found in the tables for auditing purposes are created_by, modified_by created_date and modified_date.
Monday, 5 September 2011
hibernate.hbm2ddl.auto -2
In the last article I used the SchemaExporter tool to create two sample tables. Here I shall explore the tool in more detail.The tool can be enabled by setting the below property in our cfg file:
<property name="hibernate.hbm2ddl.auto">create-drop</property>Or if we are using hibernate.properties
hibernate.hbm2ddl.auto
In our earlier post we saw how creating the SessionFactory object led to execution of DDL, if the hm2ddl property was configured. The SchemaExport or hbm2ddl can be used to generate DDL from the mapping files( or annotations).
According to the Hibernate guide
"The generated schema includes referential integrity constraints, primary and foreign keys, for entity and collection tables. Tables and sequences are also created for mapped identifier generators.You must specify a SQL Dialect via the hibernate.dialect property when using this tool, as DDL is highly vendor-specific."
"The generated schema includes referential integrity constraints, primary and foreign keys, for entity and collection tables. Tables and sequences are also created for mapped identifier generators.You must specify a SQL Dialect via the hibernate.dialect property when using this tool, as DDL is highly vendor-specific."
Configuring via properties or XML ??
The way to run Hibernate is to create a SessionFactory object. The SessionFactory Object is responsible for providing us with Hibernate sessions to perform the various db Operations. In minimal words, the Session factory is responsible for internally managing all db related operations for us.
Before using a session factory it has to be configured for use.
And then they were brought to-ogether
Continuing from the last post, now we need to execute the code. This is where we pass over the control to Hibernate and the framework takes the necessary action to create a database based on the information provided in our mapping files.
For this we need to create the cfg file.The cfg or configuration file contains all the
configuration information that is needed to get Hibernate up and running.This file must also be present on the class-path.
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory>
Creating the Relational from the Objects
Now that the Objects have been created, it is time to match them to Relational aspect of the application or the database tables.
We have an option of creating the database manually through SQL and then associating them with Objects or Classes created. Or we can do it the other way round.
In this case we proceed by first creating our Object world. Hibernate already provides users with the tools to generate the SQL scripts necessary for this purpose. We shall use the same. But the first step would be to create the mappings for Database related tables, columns, constraints etc that would be used.
This can be achieved either by mapping files or via annotations. I shall prefer the longer (but my personal favorite) hbm files for achieving this.
We have an option of creating the database manually through SQL and then associating them with Objects or Classes created. Or we can do it the other way round.
In this case we proceed by first creating our Object world. Hibernate already provides users with the tools to generate the SQL scripts necessary for this purpose. We shall use the same. But the first step would be to create the mappings for Database related tables, columns, constraints etc that would be used.
This can be achieved either by mapping files or via annotations. I shall prefer the longer (but my personal favorite) hbm files for achieving this.
Fleshing out the Models (The java ones :P) - 2
We saw the Object world in our example was composed of People and their Pets. Certain things that I would like to point out in the code from the previous post:
- Both objects have been provided with a database identifier although they include separate fields that can validate their uniqueness in the application.
- The setter methods for the identifiers have been made private as the design decision is to let hibernate set and manage the Db Identifier.
- Care has been taken to avoid using the Db managed identifier in the equals method. The reason for this can be found in the article http://community.jboss.org/wiki/EqualsAndHashCode. (In basic terms: as we are not managing it and the field is dependent on the objects existence in the database it could create a whole lot of null checks and be difficult for unique checks in Sets and Maps).
- Care has been taken in the Pets class to avoid referencing the fields of Owner class in the toString/ hash code method. In case lazy loading is being used, this could lead to the execution of a very large number of queries simply for the purpose of toString readability. The same reason is used to avoid pet references in the Owner.toString method.
- The Entities thus created do not have to be dumb representations of the database Records. It makes perfect sense to use the richness of Object Oriented Architecture and to provide business methods like Owner.addPet(). The entities need not be restricted to simple getter/setter methods.
Fleshing out the Models (The java ones :P) - 1
The way people work is that create the database separately and then create their hibernate model classes to work with the tables in the sql.
I decided to follow the process found in tutorials on the net and in the book.
I decided to follow the process found in tutorials on the net and in the book.
- Analyze and identify the domain models.
- Create the class that would represent these objects in java.
- Create the OR mapping that would link the Java Models with the database Tables.
- Let Hibernate generate the DDL and worry about all related considerations.
The unfortunate victim (or what the sensible call Domain Model)
I decided to start with a very simple application. Just two tables that could be later expanded as required.
As I already had a My SQL db installed at my home, I decided to start with the use of their sample Menagerie database.
I decide to build a simple Pet application. It would be composed of Pets and their Owners. Each Owner could have One or more pets. To simplify things I decide to restrict the Pet domain to DOGS only.
As I already had a My SQL db installed at my home, I decided to start with the use of their sample Menagerie database.
I decide to build a simple Pet application. It would be composed of Pets and their Owners. Each Owner could have One or more pets. To simplify things I decide to restrict the Pet domain to DOGS only.
First Draft Object Design |
In the Beginning (of this blog)
I have been working on Hibernate for the past year. Like all developers I learned along the way and in a haphazard manner. So when I really got the chance to study Hibernate I realized that I have been using the technology in a very flawed manner. So I decided to do what I should have done last year.
I brought a copy of the book "Java Persistence With Hibernate" and started reading it. Not finding the time to read it everyday has resulted in a longish learning curve. I have covered 20 select pages in the last 6 months. (An unsurprising observation, I have made is that all topics covered are related to all difficulties encountered in my every day work.)
So I finally decided to do things the right way. To read and to code. As I have benefited from a large variety of sites in my learning process, I decided to do the same. Share the knowledge that I gather in the process.
As I myself am on a learning process I can in no way guarantee to be giving any expert knowledge here. All I am trying is to share what I learn. Cheers.
I brought a copy of the book "Java Persistence With Hibernate" and started reading it. Not finding the time to read it everyday has resulted in a longish learning curve. I have covered 20 select pages in the last 6 months. (An unsurprising observation, I have made is that all topics covered are related to all difficulties encountered in my every day work.)
So I finally decided to do things the right way. To read and to code. As I have benefited from a large variety of sites in my learning process, I decided to do the same. Share the knowledge that I gather in the process.
As I myself am on a learning process I can in no way guarantee to be giving any expert knowledge here. All I am trying is to share what I learn. Cheers.
Subscribe to:
Posts (Atom)