[Nhib.pdf] one entity class corresponds to multiple database tables

Source: Internet
Author: User

First, let's talk about the background. In the project that was about to be launched recently, we met a customer's requirement: The table name is dynamic and determined based on some values in the database. For example

 

Requirement

The primary table student has two columns of ID and class.

Then there is an example from the xxxstudentdetail table, where XXX is the class value in the student table, and the value range is not limited.

That is to say, a studentdetail table must be added for each class type.

 

Two technical solutions were taken into consideration in the face of requirements, but they all hit the wall.

1 On namingstrategyArticleBut the reloaded classtotablename method imports the class name instead of the object.

2. The mapping information is dynamically generated at runtime, but the sessionfactory of NH has configuration. after buildsessionfactory is obtained, the configuration cannot be changed. (I tried to use reflection to forcibly Generate mapping and insert it into each dictionary in sessionfactory. However, the workload is huge, second, I have to give up without understanding the internal structure of NH)

By the way, I have also checked whether LINQ to SQL can be implemented. After reading this discussion on msdn, I feel that I can create an abstract class to map the studentdetail table using attribute, tablename is not specified. during runtime, emit is used to generate subclass of this class to map a specific table. However, the problem is that the input parameter of the reloaded gettable method is type rather than object, and the namingstrategy route of NH is stuck in the same place.

Later, the customer accepted the hard code solution of XXX (the customer also reduced the value range of XXX from around 200 to 5, otherwise, hard code will also die ...)

As a result, the technical requirement is changed to an entity class corresponding to several mappings, So we sacrifice the entity name, the main character of today.

Entity name is the new tag that appears at the beginning of nh2.1. An instance is provided on the official website. A generic class corresponds to several mappings.

Next let's take a look at mapping.

Child. HBM. xml

 

Childdetail. HBM. xml <? XML version = "1.0" encoding = "UTF-8" ?>
< Hibernate-Mapping Xmlns = "Urn: nhibernate-mapping-2.2" Namespace = "Somecompany. myschool. Persistent. Model" Assembly = "Somecompany. myschool. Persistent. Model" Default-lazy = "True" >
< Joined-subclass Name = "Childdetail" Extends = "Child" Entity-name = "Year2009class1childdetail" Table = "Year2009class1childdetail" >
< Key Column = "ID" Not-Null = "True"   />
< Property Name = "Name" Type = "Ansistring" Length = "32" />
< Property Name = "Enrolmentdate" Type = "System. datetime" Not-Null = "True" />
< Property Name = "Classname" Type = "Ansistring" Length = "32" Not-Null = "True" />
</ Joined-subclass >

< Joined-subclass Name = "Childdetail" Extends = "Child" Entity-name = "Year2009class2childdetail" Table = "Year2009class2childdetail" >
< Key Column = "ID" Not-Null = "True"   />
< Property Name = "Name" Type = "Ansistring" Length = "32" />
< Property Name = "Enrolmentdate" Type = "System. datetime" Not-Null = "True" />
< Property Name = "Classname" Type = "Ansistring" Length = "32" Not-Null = "True" />
</ Joined-subclass >

< Joined-subclass Name = "Childdetail" Extends = "Child" Entity-name = "Year2010class1childdetail" Table = "Year2010class1childdetail" >
< Key Column = "ID" Not-Null = "True"   />
< Property Name = "Name" Type = "Ansistring" Length = "32" />
< Property Name = "Enrolmentdate" Type = "System. datetime" Not-Null = "True" />
< Property Name = "Classname" Type = "Ansistring" Length = "32" Not-Null = "True" />
</ Joined-subclass >
</ Hibernate-Mapping >

 

 

We can see that the corresponding table and entity name are specified for each joined subclass. How is this entity name used? In fact, we need to create our own interceptor as follows:

Interceptor Public   Class Entitynameinterceptor: emptyinterceptor
{
Public   Override   String Getentityname ( Object Entity)
{
VaR entitynameentity = Entity As Ientitynameentity;
Return   Null   = Entitynameentity ?   Base . Getentityname (entity): entitynameentity. entityname;
}
}

 

 

You can call the configuration. setinterceptor method or use it as a parameter in opensession. For example

Public Isession getsession ()
{
Return Sessionfactory. opensession ( New Entitynameinterceptor ());
// Return sessionfactory. opensession ();
}

 

 

Of course, my childdetail class also needs to implement the ientitynameentity interface and return the value defined in the HBM file in the get method of the entityname attribute.

Childdetail Public   Class Childdetail: Child, ientitynameentity
{
Public   Virtual   String Name { Get ; Set ;}
Public   Virtual Datetime enrolmentdate { Get ; Set ;}
Public   Virtual   String Classname { Get ; Set ;}

Public virtual string entityname
{< br> Get { return string . format ( " {0} childdetail " , fullclassname) ;}< BR >}

 

 

The core implementation is as above. My colleagues can find allCode.

This article has made a lot of reference to this blog and has benefited a lot. Thank you very much. There are two more interesting points about the implementation of this blogger.

First, he uses an entity class to represent three tables with inheritance relationships. This is the opposite of a normal table to represent an inheritance tree.

Second, I also introduced the usage of dynamic component.

If you are interested, take a look.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.