This solution only applies when you already know beforehand the possible states of the Context role of the state pattern, so no states will be added in the future; otherwise another aproach would be more suitable that involves developing custom hibernate UserTypes
Class Diagram
Here is the picture of the basic class diagram that we'll use for mapping:
Hibernate Mapping
The ApplicationState object is mapped to the following SQL Table:
[id] [int] NOT NULL,
[description] [nvarchar](50) NULL,
CONSTRAINT [PK_APPLICATION_STATE] PRIMARY KEY CLUSTERED
(
[id] ASC
)
)
Taking into account what we said about the fixed states that the Application can have, we'll suppose that the APPLICATION_STATE table is already populated with data and it will be a read-only entity.
The mapping file showed in the listing below, beside the two properties of the table, also includes reference to the subclasses.
It uses the id stored in the APPLICATION_STATE table as a discriminator value to identify and determine the apropiate concrete subclass at runtime.
<hibernate-mapping> <class name="com.foo.ApplicationState" table="APPLICATION_STATE" polymorphism="implicit"> <cache usage="read-only"/> <id name="id" column="id"> <generator class="assigned" /> </id> <discriminator insert="false" column="id" /> <property name="description" column="description" /> <subclass name="com.foo.PendingApplication" discriminator-value="0"/> <subclass name="com.foo.ApprovedApplication" discriminator-value="1"/> <subclass name="com.foo.RejectedApplication" discriminator-value="2"/> </class> </hibernate-mapping>
The Application mapping refers to the state as a simple "many-to-one" property.
<hibernate-mapping> <class name="com.foo.Application" table="APPLICATION"> ... <many-to-one name="state" column="stateId" outer-join="false" lazy="false" not-found="ignore" class="com.foo.ApplicationState" > </many-to-one> ... </class> </hibernate-mapping>
So when you load the Application object, hibernate automatically grabs the according concrete ApplicationState subclass, based on the stateId stored in the APPLICATION table.
Hope this is clear enough, comment if you any question.
References
- State Design Pattern in Wikipedia
Could you send me the complete sample code? I used your solution in my application but I'm receiving a Hibernate exception...
ReplyDeleteasdsadsa
ReplyDeleteArgentina Bitcoins is focused on offering safe communications and repayments in between models online of Things. However a different one, Monero, is all about level of privacy, producing dealings between end users really anonymous and untraceable all over its block chain system.
ReplyDeleteThanks for tthis
ReplyDelete