Your new flexible Canyon based system is working wonderfully. You are enjoying the power and ease of reading and persisting data from flat files with worry. However your model has moved on. Now your model isn't exactly flat. Your model is now a graph of objects, where you now have collections, sets and objects encapsulated and stored alongside your main object.
Fortunately Canyon was designed with this purpose in mind. Canyon allows you to persist your object model with a simple call to the persist method of the relevant session. In fact you could have a session that reads for a location and another session that writes to another destination (they could be the same file, which obviously could lead to deadlock or an infinite loop!)
In terms of entity relationships Canyon supports the following. If you require the unsupported features you really need to think about whether a flat file representation is the best option for your system. Or maybe you could model your data slightly differently. Remember Canyon can use the same file to feed multiple mappings if required.
|Relationship||Supported||Description||One to One||Yes||Use the <object> element in the mapping file|
|One to Many||Yes||Use the <collection> or <set> element in the mapping file|
|Many to One||No||No capability|
|Many to Many||No||No capability|
Unlike a database Canyon only allows single field joins directly to another object. It does not map multi field or query type relationships. Canyon provides the capability to join a 'foreign' object with an entity based on the value of the id field of the entity matching the foreign field value. The foreign field is defined using the foreign_key attribute.
Also unlike a database Canyon does not scan and index the file. It relies upon the strict sequential ordering of data in the file as it iterates over the file. Remember even though in many ways Canyon provides similar mechanisms to the Hibernate ORM it is essentially iterating over a series of files.
The way this works is shown below
The mapping description shows the way the three types of mapping can be used. In each case Canyon will use the value of the id field id of the Shop object to match the foreign_key field shopId in the Manager, Product and Employee object.
For relationships to operate the id field is mandatory, as this is integral to the mechanism used.
For this example the flow of execution is as shown below.
The diagram shows that Canyon essentially chains a sequence of calls together to create the resultant object.
Each piece of the chain iterates over the configured file. Therefore using the analogy of cursor, the cursor at the end of the flow will have been moved on for all four streams (Shop, Manager, Product, Employee). So the next call for any of these class would start from the position of the cursor at that point, not from the point of the last explicit call for that particular class.
This is more clearly shown below. The diagram on the left shows that the strict order of the related objects data is required. The diagram on the right shows data that is not sequentially ordered, and therefore requires some random access capabilities which Canyon does not support. The random access style can be identified by the crossing of relationship lines. In cases like this you cannot map a relationship between the two objects. The object relationship would have to be manually controlled by the calling developer code.
It should be noted that the file formats of each class are completely independent from each other. Canyon provides the flexibility to manage different file formats and sources for each class simultaneously.