Associated classes
This lesson introduces associated classes, which are attributes of one class that references another class. By completing this module, you will learn:
- How classes can relate to each other through associations.
- How to model those associations in NexJ Studio and use the reverse property to establish a two-way association.
- How to use key indexes to capture those associations in the data store.
Create associated classes
Note
Before starting a new development task that makes changes to your model, verify that you have published the current model from the Model Library dialog. If you did not do this in the previous chapter or lesson, do so now.
In the previous lesson, you created a training:Entity
class, which models the people and companies that your business has contact with. It contains a single attribute, lastName defined as a string. Simple attribute types, such as string, integer, timestamp, and decimal are collectively called primitive types. You often need more complex data, such as a mailing address, to be stored in an attribute. In this case, you can define the attribute to be based on another class in the business model. In this case, the attribute is referred to as a complex type or a complex attribute.
When you define a complex attribute, you establish an association between the classes that you are modeling. This association can be one-way, or two-way.
Reverse property
In a one-way association ClassA
uses ClassB
as an attribute, this allows access to instances of ClassB
through instances of ClassA
. However, ClassB
instances have no way of directly accessing the ClassA
instances that they are associated with. For example, if a class Person
has a one way association to a class ContactInformation
, then an instance of Person
can access its related ContactInformation
instances, but a given ContactInformation
instance cannot access any information about the Person
instances with which it is associated.
By contrast, if these classes have a two-way association, then both sets of class instances can access each other. The instances of the Person
class can access related ContactInformation
instances and the instances of the ContactInformation
class can access their related Person
instances, allowing you, for example, to find out who lives at an address or the owners of a given telephone number.
To specify a two-way association in NexJ Studio, you use the reverse property. This property is set on a complex attribute in order to identify how the class specified by the attribute refers back to the class containing the attribute.
In this lesson you expand the business model to include the ways in which a person or business can be contacted. You add two classes to the model: training:Telcom
and training:TelcomType
. training:Telcom
models the different ways that an entity can be contacted. training:TelcomType
models the different types of telecommunication channels available.
For example, Thing2
might have a home address and a business address. These would each be training:Telcom
instances with a training:TelcomType
of Address. However, Thing2
might also have a phone number, which would be a training:Telcom
instance with a training:TelcomType
of PhoneNumber. The training:Telcom
class will have a two-way association with the training:TelcomType
class and another one with the training:Entity
class.
Create the training:Telcom
and training:TelcomType
classes. You create both classes right away so that in one class you can refer to the other class while defining the class's properties.
- In the Business Model layer, click the Classes tab.
- Right-click in the navigator and select New Class.
- Name the class
training:TelcomType
and click Finish. - Right-click in the navigator again and select New Class.
- Name the class
training:Telcom
and click Finish
Specify the details of the training:TelcomType
class. This class will have two attributes: name
, a primitive type, and telcoms
, a complex type that refers to the training:Telcom
class.
- In the navigator, double-click the
training:TelcomType
class to open it. - In the Overview tab, set the Caption property using a string resource, as you did with the
Entity
class. Set the en value toTelcom Type
. - In the Description field, enter
Types of telcoms such as Home, Business, and Mobile
. - In the Aspects field, click the Select button and add
LOCKING
. In the Attributes tab, click the Add button to add two attributes to the class. Then set their properties as follows:
Attribute descriptions for TelcomTypeAttribute Property Value Notes name Type string Required true Caption idsc.TelcomType.name Set the caption on the Common tab. Use the selection tool to create this ID and give it an en value of Telcom name
.telcoms Type training:Telcom This is a complex type referring to the training: Telcom
class.Collection true Reverse type type
is the name of the corresponding attribute in theTelcoms
class.Cascade cancel Set the cascade property on the Validation tab.
Property definitions:
Collection
Specifies that its attribute can hold multiple possible values. In the case of thetraining:TelcomType
class, it indicates that for each instance of a training:TelcomType
, there could be multiple different telecommunication channels (telcoms) of that type. For example, if there is atraining:TelcomType
instance ofHomePhone
, there can be multiple instances of telecommunication channels that are home phone numbers.
Cascade
Determines the deletion logic for the instances associated to the class through the attribute on which the property is set. In this case, setting it tocancel
ensures that atraining:TelcomType
instance can only be deleted if there are no instances of thetraining:Telcom
class associated with it. Other options are to delete the associated instances, or to clean the association between the instances.
Reverse
Establishes two-way associations between classes. In this case, setting theReverse
property on the telcoms enables you to access thetraining:Telcom
instances related to a given training:TelcomType
instance through the attribute relationship. In almost every case, the reverse property values will be reciprocal. That is, ifClassA:AttributeA
has a reverse that points toClassB:AttributeB
, thenClassB:AttributeB
will also have a reverse toClassA:AttributeA
. In this lesson, because the telcoms attribute has a reverse toTelcom:type
, then when you define the training:Telcom
class, its type attribute should have a reverse toTelcomType:telcoms
.- Save your changes.
Specify the details of the training:Telcom
class. This class has five attributes, two of which are complex.
- In the navigator, double-click the training:
Telcom
class to open it. - In the Overview tab, use the Select button to set the Caption property to a new string,
idsc.TrainingTelcom.caption
, with an en value ofTelcom
. - In the Description field, enter a value of
Telecommunications such as telephone number, email address, website address
. - In the Aspects field, click the Select button and add
LOCKING
. Add the following attributes with the specified properties to the
training:Telcom
class:
Attributes to add to the Telcom classAttribute Property Value Notes name Type string Required true address Type string Required true type Type training:TelcomType Required true Enforces that every telecommunication channel must have an associated training: TelcomType
.Reverse telcoms Completes the reciprocal relationship by indicating that the telcoms attribute of the training:TelcomType
class is itself of typetraining:Telcom
, and has a reverse value of type.entity Type training:Entity Another complex type, creating an association with the Entity
class.Required true Every Telecom
channel must be associated with a entity specificEntity
instance.Reverse telcoms Later. to complete the reciprocal relationship, you add the telcoms attribute of type training:Telcom
to theEntity
class.isPrimary Type boolean Initializer #f Set this property on the Value tab. #f
is the Scheme symbol for “false”.- Save your changes.
At this point you have completed setting up the association between the training:Telcom
and the training:TelcomType
classes. However, the training:Telcom
class also has a two-way association with the training:Entity
class, so you must update the training:Entity class as well to complete your work on the Business Model for this lesson.
Complete the relationship between the training:Telcoms
and training:Entity
classes:
- Open the training:
Entity
class. In the Attributes tab, add the following attribute and properties:
Attribute to add to the Entity classAttribute Property Value Notes telcoms Type training:Telcom Collection true Reverse entity Cascade delete Set the cascade property on the Validation tab. Info
Setting the
Cascade
property to delete causes all the associatedtraining:
Telcom
instances for atraining:
Entity
instance to be deleted when thetraining:
Entity
instance is deleted.- Click the Save button in the toolbar to save your changes.
Create a class diagram
Until this point you have modified your business model using editors to update the class properties and attributes. As your model becomes more complex, it is useful to use a visual method of exploring and editing the model. You can create UML class diagrams of your business model in NexJ Studio. You can then use the diagram to drill down into the model details and make model changes.
You can indicate an association in a type diagram in two ways:
- Class with an attribute whose type is another class (e.g.
+ type :
training:TelcomType
). - Both classes are in the diagram, connected with a line labelled with the attribute or attributes by which the classes are associated, the cardinality of those attributes, and the direction of the association.
In this lesson you create a class diagram for your model and learn how to use it to access different classes in the model.
To create a class diagram for the training:Entity
, training:Telcom
, and training:TelcomType
classes:
- In the Business Model layer, click the Diagrams tab.
- Right-click in the navigator and select New Class Diagram.
- Name the diagram
training:Entity
and click Finish. A blank canvas for the diagram appears.
You can toggle the display of the grid using the menu items View → Grid. - If the diagram palette is not shown, click on the small left-pointing arrow at the upper right of the diagram editor.
The class diagram palette appears. It can be hidden by clicking the arrow again. - With the newly created diagram open, click the Classes tab and drag the
training:Entity
class from the list into the empty canvas. A UML representation of theEntity
class appears in the diagram. Note that thetelcoms
attribute is of typetraining:Telcom
, indicating that it is an complex attribute. Note also that the brackets next to thetelcoms
attribute indicate that it is a collection of training:Telcom
instances. - Click the
training:Telcom
attribute and drag it to any open space in the diagram. The attribute disappears from thetraining:Entity
class box and is replaced by an association line between thetraining:Entity
class and thetraining:Telcom
class.
Note that there is a 0-to-many association on the telcoms indicating that eachtraining:Entity
can have any number of associated telecoms. - Expand the diagram again by dragging the type attribute of the
training:Telcom
class to any open space in the diagram. Your diagram should now resemble the following picture:
Thetraining:Entity
class has an attribute named telcoms of typetraining:Telcom
. It is also a collection, meaning that one entity can have multiple (0..*)training:Telcom
objects (home phone number, email address, mobile phone number, etc...). Thetraining:Telcom
class has an attribute named entity of type training:Entity
. You created the two-way association path between these attributes by specifying the reverse property on each of them. In this case, the telecoms attribute on thetraining:Entity
class has a reverse to the entity attribute on thetraining:Telcom
class; the entity attribute on thetraining:Telcom
class has a reverse to the telcoms attribute on the training:Entity
class. Now, given atraining:Telcom
instance, you can access its associatedtraining:Entity
instance through the association path created by the reverse properties. - To add a note to the diagram, click the Note button in the palette and then click in the upper-right hand corner of the diagram.
- Double-click the note to put it into edit mode, and enter
Telcom Model - Fundamentals Course
. Resize the note as appropriate. - Save your work.
- Validate your model.
Test the model logic
Now you test the model logic to ensure it behaves as expected.
In the scratchpad, you create script that create an training:Entity instance, define a training:TelcomType
instance, and then create a training:Telcom
instance that has associations to both of them.
Note
The steps in this lesson assume that you have carried out the steps in Test your work, in the previous module which persists some data to the model. If you did not run those steps, or if you have subsequently carried out an action that erases the data store, such as using the Data Load Tool to reset or recreate the database, then you should rerun the code from that lesson in a console before proceeding.
Use an existing or create a new scratchpad. (Resources → Scratchpads). Add the following commands to the scratchpad:
; read an entity that you created in the previous lesson and assign it to the ; variable "anEntity". read-instance is used here to find the Entity instance ; that has a lastName value of "Thing1" (define anEntity (read-instance training:Entity '() '(= lastName "Thing1") '())) ; ensure that Thing1 existed, if not create it (when (null? anEntity) (set! anEntity (training:Entity'new (: lastName "Thing1")))) ; create a new TelcomType of Home (define aTelcomType (training:TelcomType'new (: name "Home"))) ; create a new Telcom instance associated with the Thing1 entity and the ; Home telcomtype (define aTelcom (training:Telcom'new (: entity anEntity) (: type aTelcomType) (: name (aTelcomType'name)) (: address "(416) 555-1234") ) )
Run the Server Console using .
Info
The console automatically validates the model when it starts.
Select the statements you entered in the scratchpad and press Ctrl+U to run them in the console. You should see output similar to the following:
; 12:16:17,507 DEBUG [SQLAdapter] select A.id, A.locking from NJEntity A where A.lastName = ? ; 12:16:17,508 DEBUG [SQLAdapter] Bind[0] = 'Thing1' ; 12:16:17,512 DEBUG [<default>] Activated SQLConnection@1317264939(pool=RelationalDatabaseConnectionPool(fragment=RelationalDatabaseFragment DefaultRelationalDatabase.<default>)) ; 12:16:17,579 DEBUG [SQLAdapter] SQL execution time: 67 ms ; 12:16:17,580 DEBUG [SQLAdapter] Retrieved 1 instance(s) of Entity in 1 ms ; #<Instance<Entity, OID:1:V32:D2F82A01DE0A44FCB5807316DFCEB65F, CLEAN>(locking=0)> > ; 12:16:17,583 DEBUG [TelcomType] Invoking Event TelcomType.new(values) ; 12:16:17,588 DEBUG [GenericTransactionManager] Starting new transaction Tx(00000000000000005A1438C0B5F97552370ADC03C577DE56) ; 12:16:17,588 DEBUG [InvocationContext] Started new transaction Tx(00000000000000005A1438C0B5F97552370ADC03C577DE56) ; 12:16:17,589 DEBUG [<default>] Deactivating SQLConnection@1317264939(pool=RelationalDatabaseConnectionPool(fragment=RelationalDatabaseFragment DefaultRelationalDatabase.<default>)) ; 12:16:17,591 DEBUG [TelcomType] Invoking Event TelcomType.create() ; #<Instance<TelcomType, null, NEW>(name="Home")> > ; 12:16:17,592 DEBUG [Telcom] Invoking Event Telcom.new(values) ; 12:16:17,595 DEBUG [Telcom] Invoking Event Telcom.create() ; #<Instance<Telcom, null, NEW>(name="Home", address="(416) 555-1234", type=Instance<TelcomType, null, NEW>, entity=Instance<Entity, OID:1:V32:D2F82A01DE0A44FCB5807316DFCEB65F, CLEAN>)> >
Stop the Console by clicking the Terminate button .
Create the class persistence mapping
Now, use the Persistence Mapping tab to manage the persistence mapping of the class attributes to the data sources that you have defined.
Instead of using the navigator to access the class details, this time you use the class diagram.
To enable persistence for the Telcom
class:
- Open the
training:Entity
class diagram (Business Model → Diagrams). - Double-click the title of the training:
Telcom
class. The training:Telcom
class opens in the editor. - Click the Persistence Mapping tab.
- Set the Data Source property to
DefaultRelationalDatabase
. - Set the Primary Table to Training
Telcom
. - In the Key Generator field, select KeyGenerator.GUIDGen (GUID key generator).
- To define which attributes have their data stored in the database, click the Select Attribute Mappings button and select the following attributes:
- name
- address
- type
- entity
- isPrimary
Thename
,address
, andisPrimary
attributes appear in the Primitive Attributes list. Thetype
andentity
attributes appear in the Association Attributes list.
To complete defining the associations between the
training:Telcom
class and the associated classes, set the Source Key, and Destination Key values for the Association Attributes according to the following table.
Association attribute mapping for the Telcom classAttribute Source Key Destination Key type TrainingTelcom.FK_TelcomType entity TrainingTelcom.FK_Entity Leave the key blank if you are specifying the object key (AKA primary key)
The
type
andentity
attributes are complex, and associated with thetraining:TelcomType
and training:Entity
classes, respectively. For each of these, the source key indicates an index associated with the class being persisted, and the destination key indicates an index on the associated class. The values of the columns indexed by these keys will be coordinated to track the association of the class instances.Save your work.
Click Update Data Source to apply these changes to the DefaultRelationalDatabase.
Click OK on the Update Data Source window.
You are taken to the properties of the
DefaultRelationalDatabase
in the Data Sources tab of the Persistence layer.On the General tab add
Stores Telcom objects for an Entity.
as the Description.Set the case insensitive flag for the id column to false.
Columns for the primitive attributes, including the id
column used for the index have been created for you, as well as the primary key index. However, you need to add the columns and the indexes that are used to define the associations with other classes.
To create the columns and indexes to define the associations:
In the Columns tab, click the last attribute, then click the Add button to add the following two columns:
Column properties for the TrainingTelcom tableColumn Name Type Allocation Allow Nulls Precision Case Insensitive telcomTypeId binary fixed false 16 false entityId binary fixed false 16 false - Deselect the Case Insensitive property of the
id
column. In the Indexes tab, add the following two indexes:
Index properties for the Telcom tableName Type Unique Index Columns TrainingTelcom.FK_TelcomType btree false telcomTypeId TrainingTelcom.FK_Entity btree false entityId Info
The TrainingTelcom.FK_TelcomType index is used to instantiate the association between the
training:
Telcom
andtraining:
TelcomType
classes through their respective type and telcoms attributes. Likewise, the TrainingTelcom.FK_entity index establishes the association between thetraining:
Telcom
andtraining:
Entity
classes. Foreign keys act by taking on values of the (usually primary) keys of other tables.- Save your work.
Return to the training:Entity
diagram so that you can enable persistence for the training:TelcomType
class.
- Double-click the
training:TelcomType
class and select the Persistence Mapping tab. - Select the DefaultRelationalDatabase as the Data Source.
- Set the Primary Table as
TrainingTelcomType
and specify the Key Generator of KeyGenerator.GUIDGen. - Click the Select Attribute Mappings button and add the name and
telcoms
attributes. Set the Name, Source Key, and Destination Key values for the
telcoms
attribute according to the following
table.
Association attribute mapping for the TelcomType classAttribute Source Key Destination Key telcoms TrainingTelcom.FK_TelcomType - Save your work.
- Click Update Data Source to apply these changes to the DefaultRelationalDatabase. Click OK on the Update Data Source window.
- You are taken to the properties of the
DefaultRelationalDatabase
in the Data Sources tab of the Persistence layer. - In the General tab add
Stores Telcom types
. as the Description. - In the Columns tab, deselect the Case Insensitive property of the
id
column. In the Indexes tab, add the following index:
Index properties for the TelcomType tableName Type Unique Index Columns TrainingTelcomType.OK_Name btree true name Info
The TrainingTelcomType.OK_Name index ensures that all names in the class are unique. The acronym OK is used to signify "other key," i.e. a key that is neither the primary key nor a foreign key.
- Save your changes.
Return to the training:Entity
diagram so that you can enable persistence mapping for the Entity
class:
- In the
training:Entity
diagram, double-click theEntity
class. The class opens in the editor. - Click the Persistence Mapping tab.
- Click the Select Attribute Mappings button and add the
telcoms
attribute. Set the Source Key, and Destination Key values for the
telcoms
attribute according to the following table.
Association attribute mapping for the Entity classAttribute Source Key Destination Key telcoms TrainingTelcom.FK_Entity Note that the source key for the
Entity:telcoms
attribute was the destination key of theTelcom:entity
attribute. Likewise, the source key of theTelcom:entity
attribute is the destination key of Entity:telcoms.
This completes the mapping required to instantiate the association between theTelcom
andEntity
classes.
No changes to the data source are required.- Save your work and validate the model.
Edit the upgrade file
Now that you have defined the logical database structure and the persistence model, make changes to the upgrade file so that you can upgrade your physical database and model dump file.
To update the upgrade file:
- In the Persistence layer on the Data Sources tab right-click the
DefaultRelationalDatabase
and select Generate Upgrade Steps. - Leave the default values for Upgrade and Current Data Source.
- Select Old Model as the Old Data Source. You are going to use a published model as the old model.
- Select Published Model JAR and then click the browse button. Select the model you published at the end of the last lesson and click Next.
- Whenever you upgrade a database, you must increment the version number by a whole number. e.g. If the version retrieved from the published JAR file is 2.39; change the Version to
3.39.
- Enter the following as the Description:
Added telcoms support.
- One the left side you can see a list of the upgrade steps that will be applied to the database. There are two CreateTable steps: one for the
training:Telcom
table and one for thetraining:TelcomType
table. For each table, click the Columns and Indexes tabs to review how the tables will be created. - Click Finish to create the upgrade steps.
- You must ensure that your current model's version matches the upgrade version. Click the Set current model button in the toolbar to open the Model Library.
- With the current model selected, click Edit. Update the Model Version field to match the version associated with the upgrade you just created. So, if your upgrade is associated with version
3.39
, then change the Model version to3.39
. This enables NexJ Studio to recognize that the model has been changed from the previous version so that your update can be applied to the supporting data stores. - Click OK. Notice that the new version is now reflected in the table in the Models tab.
- Click the Save button in the toolbar to save your work.
Publish the model
Publish the updated model from the Model Library. This is important so that future lessons will know what the state of the data model was in the past.
- Click the Set current model button to open the Model Library.
- Select the
training
model. - Click Publish. The Publish Model window opens.
- Select the folder that you want to publish your model to. The default value should be correct.
- Click Save. Click Close.
The Console view lists the actions taking place as NexJ Studio publishes the model. If the publish is successful, you will see the message
BUILD SUCCESSFUL
.Info
If the model contains any warnings or errors, you are prompted to confirm whether you want to continue publishing. For the purposes of this tutorial, it is OK to have warnings, but not errors, when you publish.
Upgrade the database
Use the Data Load Tool to apply the changes from the upgrade file to the physical database:
- Launch the Data Load Tool by clicking the drop-down arrow next to the Run tool button in the toolbar.
- In the Model section, select Current.
- In the Server and Connection field, ensure that the Test option is cleared.
- In the Server field, select Development(development) (environment).
You must select this environment because you need to use a user with permissions to change to the database table structure. - In the Command field, select upgrade.
- In the Data Source field, select *.
- Select Ignore Upgradable Flag.
- Click Run. Confirm that you want to perform the upgrade action against a non-test connection.
To verify that the upgrade worked:
- Run your database's management tool or query client.
- Verify that the table
NJTrainingTelcom
exists with the proper column definitions in the training database:- For Microsoft SQL Server use the
exec sp_help NJTrainingTelcom
statement.
- For Microsoft SQL Server use the
Test your work
Test your work by confirming that you can persist training:Telcom
and training:TelcomType
instances to the database.
To persist instances to the database:
- Start the Server Console in Debug mode.
- Open an existing or create a new scratchpad.
Previously, you created classes in the Console that were not persisted. This time you use the (
commit
) command to save the data in the database.
Add the following command to the end of the existing code :(commit)
- Select all the code and press Ctrl+U to run it.
Inspect the console output, which should resemble the following:
> (define anEntity (read-instance training:Entity '() '(= lastName "Thing1") '())); 11:32:39,280 DEBUG [Entity] Invoking Event training:Entity.read(attributes, where, orderBy, count, offset, xlock) ; 11:32:39,280 DEBUG [GenericTransactionManager] Starting new transaction Tx(0100000000000000957F8007248ECAAF3255D10A83E37864) ; 11:32:39,280 DEBUG [InvocationContext] Started new transaction Tx(0100000000000000957F8007248ECAAF3255D10A83E37864) ; 11:32:39,280 DEBUG [SQLAdapter] select A.id, A.locking from NJTrainingEntity A where A.lastName = ? ; 11:32:39,280 DEBUG [SQLAdapter] Bind[0] = 'Thing1' ; 11:32:39,280 DEBUG [GenericConnectionManager] Activated connection SQLManagedConnection@18170911(user=sa, factory=SQLManagedConnectionFactory({serverName=localhost, maxStatements=0, lobBuffer=10485760, prepareSql=3, databaseName=test101b, appName=NexJ, bufferMaxMemory=65536, xaEmulation=true, sendStringParametersAsUnicode=true})) ; 11:32:39,312 DEBUG [SQLAdapter] SQL execution time: 32 ms ; 11:32:39,312 DEBUG [SQLAdapter] Retrieved 1 instance(s) of Entity in 0 ms ; #<Instance<training:Entity, OID:1:V32:A8D16D8698BB4AE092FB24462FF3BBC1, CLEAN>(locking=0)> > (define aTelcomType (training:TelcomType'new (: name "Home"))); 11:32:41,999 DEBUG [TelcomType] Invoking Event TelcomType.new(values) ; 11:32:41,999 DEBUG [training:TelcomType] Invoking Event training:TelcomType.create() ; #<Instance<training:TelcomType, null, NEW>(name="Home")> > (define aTelcom (training:Telcom'new (: entity anEntity) (: type aTelcomType) (: name (aTelcomType'name)) (: address "(416) 555-1234"))) ; 11:32:44,952 DEBUG [training:Telcom] Invoking Event training:Telcom.new(values) ; 11:32:44,968 DEBUG [training:Telcom] Invoking Event training:Telcom.create() ; #<Instance<training:Telcom, null, NEW>(name="Home", address="(416) 555-1234", type=Instance<TelcomType, null, NEW>, entity=Instance<training:Entity, OID:1:V32:A8D16D8698BB4AE092FB24462FF3BBC1, CLEAN>)> > (commit) ; 11:32:47,202 DEBUG [training:TelcomType] Invoking Event training:TelcomType.commit() ; 11:32:47,202 DEBUG [training:Telcom] Invoking Event training:Telcom.commit() ; 11:32:47,202 DEBUG [training:TelcomType] Invoking Event training:TelcomType.load(attributes) ; 11:32:47,202 DEBUG [training:Telcom] Invoking Event training:Telcom.load(attributes) ; 11:32:47,202 DEBUG [training:Telcom] Invoking Event training:Telcom.load(attributes) ; 11:32:47,202 DEBUG [UnitOfWork] Committing 2 instance(s) ; 11:32:47,202 DEBUG [SQLAdapter] insert into NJTrainingTelcom(id, name, address, telcomTypeId, entityId, isPrimary, locking) values (?, ?, ?, ?, ?, ?, ?) ; 11:32:47,202 DEBUG [SQLAdapter] Bind[0] = 444882F001E3470EB297EF54E913351D ; 11:32:47,202 DEBUG [SQLAdapter] Bind[1] = 'Home' ; 11:32:47,202 DEBUG [SQLAdapter] Bind[2] = '(416) 555-1234' ; 11:32:47,202 DEBUG [SQLAdapter] Bind[3] = 1BB9C0FC578443A194BC68EC259A12DA ; 11:32:47,202 DEBUG [SQLAdapter] Bind[4] = A8D16D8698BB4AE092FB24462FF3BBC1 ; 11:32:47,202 DEBUG [SQLAdapter] Bind[5] = 0 ; 11:32:47,218 DEBUG [SQLAdapter] Bind[6] = 0 ; 11:32:47,265 DEBUG [SQLAdapter] SQL execution time: 47 ms ; 11:32:47,265 DEBUG [SQLAdapter] insert into NJTrainingTelcomType(id, name, locking) values (?, ?, ?) ; 11:32:47,265 DEBUG [SQLAdapter] Bind[0] = 1BB9C0FC578443A194BC68EC259A12DA ; 11:32:47,265 DEBUG [SQLAdapter] Bind[1] = 'Home' ; 11:32:47,265 DEBUG [SQLAdapter] Bind[2] = 0 ; 11:32:47,280 DEBUG [SQLAdapter] SQL execution time: 15 ms ; 11:32:47,280 DEBUG [InvocationContext] Committing transaction Tx(0100000000000000957F8007248ECAAF3255D10A83E37864) ; 11:32:47,280 DEBUG [GenericTransactionManager] Committing transaction Tx(0100000000000000957F8007248ECAAF3255D10A83E37864) ; 11:32:47,280 DEBUG [GenericConnectionManager] Deactivating connection SQLManagedConnection@18170911(user=sa, factory=SQLManagedConnectionFactory({serverName=localhost, maxStatements=0, lobBuffer=10485760, prepareSql=3, databaseName=test101b, appName=NexJ, bufferMaxMemory=65536, xaEmulation=true, sendStringParametersAsUnicode=true})) ; 11:32:47,280 DEBUG [UnitOfWork] Commit completed ; ()
Verify that the data was correctly persisted by querying the database. Execute each of the following queries one by one:
Microsoft SQL Serverselect entityId, telcomTypeId, name from NJTrainingTelcom select id, lastName from NJTrainingEntity select id, name from NJTrainingTelcomType
Info
The
entityId
is a reference to the record id in theEntity
table. Similarly, thetelcomTypeId
is a reference to the "Home" training:TelcomType
record. This is where you see the Source Key and Destination Key properties in action.