Nhibernate question about extension object without changing the original mapping - nhibernate

Say i have a cms with only one object called Article (for the sake of this example) with an ID and a title. This CMS implementation becomes part of a framework and is used as a library: e.g. CMSFactory.CMS.SaveArticle(a);
The problem is that depending on the project requirements an article object may have more fields such as SomeDate. Is there any way to declare this relationship and still save an article with all its extra (project-dependent) fields without changing the base CMS library (but able to declare new mappings or so)?

You could create a subclass of Article with the specific fields for the project:
class SpecialArticleForThisProject: Article {
public DateTime SomeDate {get;set;}
}
And map SpecialArticleForThisProject using one of the three inheritance mapping strategies.
The base CMS library wouldn't require any changes.

Related

How to order collection columns in Apache isis?

I am using apache ISIS for almost a year and it is a great framework. I am trying to improve the usability of the generated user interface and I am looking for a way to order the columns of a collection as displayed on the screen.
I could not find a way to order the columns using #Collection or #CollectionLayout and could not find an example if it is possible in the layout.xml file.
It would really improve the usability of my user interface if the most relevant columns of a collection would be displayed first - on the left side of the table - in the table view.
(My domain entities showed in a collection property often have a super class defining common fields. The display of attributes of a single entity is perfect using layout.xml and the bootstrap layout, but I still looking for a similar construct for collections displayed as tables in the user interface. I could not find any hints in the documentation or the advanced guide).
Thanks for any hints how I could control the order of columns in a table displaying a collection of domain entities and improve the user interface usability.
nice to know you're enjoying using the framework.
The way to do this with annotations is using #MemberOrder, not #CollectionLayout.
However, if you have a layout.xml file then this (should) override the #MemberOrder annotation. In which case, the order of the columns is the same as the order of the properties in the layout.xml.
You can also use the <collection id="xxx" hidden="ALL_TABLES"> (or alternatively #CollectionLayout(hidden=Where.ALL_TABLES)) to hide properties that you don't want to appear as columns.
All that said, I did recently discover what I think is a bug (on 1.13.0): that the layout.xml seemed to be being ignored for the collection order, even though used for the object form. This isn't consistent and I haven't got to the bottom of it. My workaround was to just add in the #MemberOrder annotations back in; this did the trick.
One other caveat: if you have a complex mix of tabs and regular fieldsets, then you'll find that those properties in tabs are considered to be first, even if there's a property in a fieldset that comes before it. This is arguably a bug, but it's a symptom of the implementation: the code does a deep traversal of tabgroups/tabs before the fieldsets.
Finally, here's a trick. What you could do is to define a bunch of derived properties on the entity for which you want to show in columns, and configure so that only these are shown in tables, and are hidden in object form, eg:
public class Customer {
#Getter #Setter private String name;
public String getNameAsColumn() { return getName(); }
}
then in the layout.xml:
<property id="name" hidden="ALL_TABLES"/>
<property id="nameAsColumn hidden="OBJECT_FORMS">
<named>Name</named>
</property>
HTH
Dan

Need help with application design (MVC, classes etc.)

I'm pretty new to object oriented programming (do have scripting knowledge in PHP and Posix shell programming) and I'm working on a beer recipe application. I've already started the project, but I guess the design is not that good from a MVC point of view. I hope you will help me get the design right. Here are a couple of things to know about the application.
The application needs to be a Document Based Application (open/save recipes in Beer XML). The main window has several textfields to set information like: name, beertype, volume etc. Then there are a couple of tableviews with arrays for: malts, hops and spices, each having their own sheet for adding values.
How should I make my classes? Like this?
NSDocument class (with the open/save XML code)
(3x) NSWindowController (for each sheet: malts, hops, spices)
(3x) NSArrayController (for each tableview: malts, hops, spices)
Should the arrays, managed by the NSArrayController objects, be separate classes (in a MVC perspective (as Model)) or should they be incorporated into their NSArrayController class?
I would start by brushing up on a couple of Apple provided docs:Object-Oriented Programming with Objective-C and Cocoa Fundamentals Guide.
I would also look at using Core Data. With relatively little implementation you have a very powerful data structure (the M in MVC) that is easy to implement with your view and view controllers (the V & C):
Core Data Programming Guide
I highly recommend reading these. They are not bad reads and you gain a TON of knowledge. Apple docs are really the best.
Good luck.
Assuming that these are your requirements,
Editor application that uses xml (beerxml) as it datasource.
Viewer that shows the available data (in a tabular format or as sheets)
User can add/remove/edit entries in each xml
There exists a relationships between the xmls (datasources) (unsure...)
Before applying any design pattern, you should start applying the basic OOP concepts to identify and create classes (state and behavior) and define the relationship between the classes.
For example, receipes.xml is used to denote the recipes used to manufacture a product. To design a class for this go through the xml. You can identify the following data classes (objects i.e. instances of classes represent a real world entity, while the class is more like a template/blue print for the object):
Recipe (main class)
Hop
Fermentable
Yeast
Water
Style
Equipment
Mash
MashStep
and so on.
Once you have identified the classes that form your data model (information repository), identify the properties and behavior of each class. For example, the Yeast class would contain the properties, Name, Version, and so on. Do not worry about the type of the property (string, integer, etc.).
To identify the controllers, view the application from the point of view of the user. What are the use cases (what does the user do with the application? Edit? Add? etc.). These use cases will inadvertently require processing information in a particular flow (sequence). The information is available in your model classes. The controller will invoke operations on the model classes and determine the interaction between them.
For example, suppose there is a use case that the use needs to add a new yeast to the system. Then the controller would create a new instance of the Yeast class and populate it with values supplied by the user (after performing some sort of validation). The created yeast would then be added to the ListOfAvailableYeasts and made available to other classes.
The view is (as the name suggests), a user interface to your data. In MVC, the view is usually updated by an observer that monitors the model for changes and updates the UI accordingly (there are several variation to MVC pattern).
The main point here is that you should first focus on object orientation design first rather than jumping directly into the design patterns.
If you need some guidelines on how to create classes from the xml, then take a look at the xsd.exe tool. You can generate the xsd (xml schema) from an xml and then use this xsd to generate a class hierarchy for the xml (I suggest you start with recipes.xml). You can modify the generated classes to your requirement.
The generated classes would look something like this,
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class RECIPESRECIPE {
private string nAMEField;
private string vERSIONField;
private string tYPEField;
private string bREWERField;
private string aSST_BREWERField;
private string bATCH_SIZEField;
...
}
Hope that this is sufficient to get you started.

NHIbernate Load via QBE with single column PK

When invoking Session.Load where the class in question contains a composite id, Load expectes the provided criteria to be an example of the object in question with all the PK properties filled in. The problem is that I want to create a generic IRepository interface with a single Load method, always providing a QBE. However, it seems that Load can not handle QBE if the PK is only a single property. Any thoughts?
Have a look at the repository interfaces in the S#arp Architecture project. They expose two interfaces that allow for a standard integer id as well as another other type (eg. your composite key object) to be specified for Get and Load operations. This is probably the route I would take in your case.

NHibernate: completely overriding base domain entity

I have a situation where I have a Common.Domain.Person and Specific.Domain.Person.
First one should be provided as a part of a common package.
Second one appears when common package has to be customized to fit the needs of specific project.
In the object model, it can be easily implemented with inheritance.
In the NH mapping, however, I have encountered a small problem.
I can create an NHibernate <subclass> mapping, but that would require me to use an discriminator. However, I know that if specific person class was inherited, then common class instances will never be used within this specific project.
What is the best way to implement this without adding discriminator column to the base class (since there are no different cases to discriminate)?
this is what i wanted and nhibernate supports it using xml entities. Unfortunately this feature has been borked since (at least) NH v2++.
see also Using Doctype in Nhibernate
A work-around could be to inject these properies programmaticaly when you create the SessionFactory (Dynamic Mapping)
see also http://ayende.com/Blog/archive/2008/05/01/Dynamic-Mapping-with-NHibernate.aspx
Just map the Specific.Domain.Person and leave Common.Domain.Person unmapped.
If you are not saving instances of it, NHibernate does not need to know about it.

How do you map an entity -> interface relationship using Fluent NHibernate?

given the following class definition:
public class Order {
public IProduct Product {get;set;}
}
I have this (fluent) mapping
References(x=>x.Product, "ProductId");
And get this exception: An association from the table Orders refers to an unmapped class, which makes sense because it doesn't know what implementation I will pass to it.
I understand why I have to define the type in the mapping (IProduct could be anything) but I'm not sure how to do it.
Thanks,
Kyle
I think what you're looking for is .References<Product>(x=>x.Product, "ProductId");
Incidentally the same is true for .HasMany<>
This seems to do the same as <... class="Product" /> in xml
I wouldn't recommend mapping to the interface as it breaks the whole point of using one - you run into problems as soon as it starts implementing IStorable and NH can't cope with the multiple inheritance.
Try mapping the interface IProduct instead of the concrete class Product. (Note, I'm not talking about mapping the Product field of class Order.)
You could map the interface->implementation relationship as an inheritance relationship, using an appropriate inheritance model.
That would mean mapping IProduct and then creating a subclass map of Product in the IProduct mapping, for example using table-per-hierarchy.
That would also let you map additional data in the product class that is not part of the IProduct interface, and also let you map additional IProduct implementations in the same way if you wish to.
I've been working on improving the support for proxy interfaces in Fluent. There were a couple of useful patches attached to issues 256 and 257, but they really needed everything specified manually. I've taken these a step further and added support for setting proxies and changing the types of references from the inferred (which would be the proxy) to the underlying mapped class, and added a new convention (ProxyConvention) to set it all up automatically - just instantiate it with a function to derive the proxy interface from a mapped class, and it should take care of the rest.
The one loophole at the moment is that it can't pick up any definitions specified explicitly in .hbm.xml files.
The patch is attached to issue 256