NHibernate Source Analysis Five: Object Identification

zhaozj2021-02-16  136

The object identity is equivalent to the primary key in the data table, plays a very important role in the persistence, NHibernate identifies whether two persistent objects are equal.

In the mapping file, the object identity is defined by the id attribute, as follows:

Where the Unsaved-Value property is used to indicate the value of the object that is not persisted. If this value does not match the unmissive object identifier value, the generator is used to specify the type of identification object, which is common to Identity, Assigned, etc. .

Identify the object to implement the class of the IIDentitiergenerator interface, created by the IdentitiergeneratorFactory class based on the type of mapping file, IIDENTIFIERGENERATOR defines the generate method to generate object identity.

1. The establishment of the identification object is created in the persistent class AbstractityPersister, and we can operate the identity of the persistent object by it.

// *** AbstractityPersister.cs ***

Public Virtual IIDENTIFIERGENERATOR IDENTIFIERGENERATOR {

Get {

IF (idgen == NULL) {

Throw new hibernateException ("...");

}

Return IDgen;

}

}

IDGEN is assigned in the constructor.

Protected AbstractityPersister (PersistentClass Model, iSessionFactoryImplementor Factory) {

// ...

// generator

IDGEN = Model.Identifier.createIdentifiergenerator (DIALECT);

UseidentityColumn = idgen is identitygenerator;

IdentitySelectString = UseIdentityColumn? Diagect.IdentitySelectString: NULL;

// ...

}

Where model is PersistentClass or its subclasses, Identifier is the properties of the Value type.

// *** Value.cs ***

Public Iidentifiergenerator CreateIdentifiergenerator (Diagect.DiaLect Dialect) {

IF (UNIQUEIDENTIFIERGENERATOR == NULL) {

UNIQUEIDENTIFIERGENERATOR = IdentifiergeneratorFactory.create (IdentifiergeneratorStrategy, Type, IdentifierGeneratorProperties, Diagect);

}

Return UniqueIndifiergenerator;

}

// *** identitifiergeneratorfactory ***

Public Static IIDentifiergenerator Create (String Strategy, ITYPE TYPE, IDICTIONARY PARMS, DIALECT.DIALECT DIALECT) {

Try {

System.Type Clazz = (System.Type) iDGenerators [Strategy];

// ...

IF (CLAZZ == NULL) CLAZZ = System.Type.gettype (Strategy);

IIDENTIFIERGENERATOR IDGEN = (iidentifiergenerator) Activator.createInstance (CLAZZ); iF (iConfigurable) .configure (Type, PARMS, DIALECT);

Return IDgen;

}

Catch (Exception E) {

Throw new mappingexception ("Could Not Instantiate ID Generator", E);

}

}

The CREATE method creates an identification object by identifying the object class name.

2. Identifies the use of objects in persistence

In a session and persistent operation, I have mentioned that the current session will store the object to persistence until Flush or shut down the session. The collection of persistent objects is EntitiesbyKey, which is a HashTable, its key is a KEY object, Value is a persistent object, the Key object is simple to store the ID and IdentifierSpace for a long-lasting object.

When the persistence operation is performed, NHibernate must first check if the object is in EntitiesbyKey, which is completed by the getentity method, and then subsequently processed in the collection.

// *** sessionImpl.cs ***

Public Object GetEntity (Key Key) {

Return EntitiesbyKey [key];

}

Let's take a look at the processing in doupdate:

Private void Doupdate (Object Obj, Object ID) {

// ...

Key Key = New Key (ID, PERSISTER);

Object Old = geTENTITY (KEY);

IF (old == obj) {

Throw new assertionfailure ("Hibernate Has A Bug in Update () ... or you are using an illegal id type");

}

Else if (OLD! = NULL) {

Throw new HibernateException ("ANOTHER Object Was Associated with this ID (The Object with the given id was already loaded));

);

// ...

Addentity (Key, Obj);

Addentry (Obj, Status.Loaded, Null, ID, Persister.getversion (Obj), LockMode.none, True, Persister;

// ...

}

If Update is performed for the first time, the OLD is empty, the operation is smooth, and the object is added to the collection.

When UPDATE is called again (in the same session, and no call can cause the Flush operation), the OLD is not empty, which will lead an exception.

转载请注明原文地址:https://www.9cbs.com/read-7952.html

New Post(0)