Question about components

Hi VP,

I’m testing once again with ORM components, and I have a question about how to use them 8)

Initially, I wanted to work with the model of Image1. The reason is that I have a large amount of objects which were associated with a small class, and I try to convert that small class into an ORM Component to save tables in the DB.

But… that small class was abstract and the concrete classes that generalize it have some different attributes. So I was wondering if I could put all this attributes into several ORM Component classes (generalizations of one single parent, abstract), and then associate this single abstract parent with the ORM Persistent class. What? :shock:

It’s easier than it seems after reading me :stuck_out_tongue: (excuse my strange explanation). The Image1 shows nearly that. The original picture was nearly the same, but replacing ORM Components with ORM Persistable entities.

So, are you ready to launch? Well… I try syncing to ERD and… the generated Entity only has “global1” attribute :cry: all the other attributes stored in generalized classes were lost from persistence.

Maybe this is what is was supposed to happen. So I ended up with the model shown in the second picture, Image2. This time, I think that the model is ok because the generated Entity has all the fields (Image3) defined :smiley:

Uhm… but a closer look told me that the “childParams_child1_paramOne1” is set as “Nullable=false”. Oops… what happens if my code does something like:


Parent parent=new Parent();
parent.childParams=new ChildParams();
parent.childParams.child2=new Child2();

Save(parent) etc...

I think that NHibernate will complain because the reference to child1 was not set. So, maybe the only solution is to use a “null object” previously created, with all the values set to something special, that later will be recognized as a “null component”. Something like:


parent.childParams.child1=nullChild1; (previously created)

But then, I remembered that I have read something about this problem. And finally found it. Paraphrasing Kuate (from “NHibernate in action” book, Manning EAP 2007, a fantastic book):

“There is no elegant way to represent a null reference to a Component. In lieu of an elegant approach, NHibernate represents null components as null values in all mapped columns of the component. This means that if you store a component object with all null property values, NHibernate will return a null component when the owning entity object is retrieved from the database.”

So, I think that this can be solved with that int parameter set as “nullable”, as well as all the others. I set the multiplicity to “0…1” to make this happen, but it did not :wink:

Is it all ok? or maybe I am confused about some theoretical concepts? Please let me know :slight_smile:

As always, many thanks for all your support
Image1.png
Image2.png
Image3.png

Hi distansia,

Initially, I wanted to work with the model of Image1. The reason is that I have a large amount of objects which were associated with a small class, and I try to convert that small class into an ORM Component to save tables in the DB.

ORM Component classes do not support inheritance. This is a limitation of NHibernate. The design presented in Image2 solve this problem :smiley:

Is it all ok? or maybe I am confused about some theoretical concepts?

I am afraid your suggestion cannot be fulfilled. According to your description, setting the multiplicity of the component to be 0…1 causes all the related column’s nullable to be true upon synchronization, if 1, then nullable will be false. But in real case it is uncommon for all the columns to be either true or false. Therefore, I’m afraid we could not make this assumption…

Best regards,
Jick

[quote=Jick]
ORM Component classes do not support inheritance. This is a limitation of NHibernate. The design presented in Image2 solve this problem :D[/quote]
Thanks for clarifying this :smiley: I thought I was swimming into troubled waters.

Uhm… In fact, it happens just the opposite :smiley: I mean, the Component’s columns multiplicities are left as they were.

In detail:

  • (paramOne1: int) in Child1 is left as nullable=false
  • (paramOne2: string) in Child1 is nullable=true (but that is because it is a string)
  • (paramTwo1: double) in Child2 is left as nullable=false

So, the sentence “NHibernate represents null components as null values in all mapped columns of the component” can not be fulfilled, because the components columns are not nullable.

Sorry, this has to be a misunderstanding between you and me :smiley:
(I am spanish, my english could be better!!)

Ok, maybe this is the case. In that situation, I will test if this works (in code) if all the attributes of the component are set to multiplicity=0…1. Then it is probably that this will do the trick. I will tell you my findings about that.

Thanks for your info!!

Hi distansia,

Do you mean synchronizing from Class Diagram to ERD should not update the nullable’s value according to the multiplicity set on the ORM Component? Sorry for my bad English skill. Would you mind explaining a little bit more? Really sorry…

Best regards,
Jick

Hey, don’t worry :smiley: I think you read my message while I was still editing it. Maybe now it is clearer (I added some more explanations).

If not clear, what I exactly mean is:

  • I want a component to be “nullable”. Following the previous example, I could be able to do this in code:
    Parent parent=new Parent();
    parent.child1=new Child1();
    dao.save(parent);

And all ok. But it is not working (it throws a persistent exception) because parent.child2 has not been set, despite of having set its multiplicity to 0…1.

This is a known problem with components, that is what Kuate (et al.) tells in his book (the paragraph about component nullability I previously quoted).

But he also says that NHibernate can “understand” that a component reference is null, if ALL its attributes are null. So, I think they are only two options left in this case:

  • If component multiplicity is set to 0…1, DBVA should also set all the synchronized entity columns to be nullable=true

or

  • If this assumption can not be made (maybe are some general cases where this does not apply), then the user MUST manually set the multiplicity of all the attributes of the component to 0…1 (I will test this when I will be in front of Visual Studio, and will tell you my findings)

Anyway, if the second option is the only available, a feature suggestion will be that DBVA have a “tool”, or “command” like: “Do you want to set all attributes to multiplicity=0…1? Yes/No”

But wait, I will test this soon and will tell you :smiley:

Best regards

Hi distansia,

I will discuss with our engineers first. :slight_smile:

Best regards,
Jick

[quote=Jick]Hi distansia,

I will discuss with our engineers first. :slight_smile:

Best regards,
Jick[/quote]

Hi Jick,

Any news about this topic?

Hello distansia,

Sorry about this. After a series of discussion, we listed out as many cases as we can, and decided not to take any action at this moment. This is because an ORM Component can contain another ORM Component. If the chain is very long, the calculation of nullable or multiplicity will be hard to determine, and error prone. User may not understand why it is true/false for nullable, too. Therefore, I am sorry for this bad news.

Best regards,
Jick

[quote=distansia]- If this assumption can not be made (maybe are some general cases where this does not apply), then the user MUST manually set the multiplicity of all the attributes of the component to 0…1 (I will test this when I will be in front of Visual Studio, and will tell you my findings)

Anyway, if the second option is the only available, a feature suggestion will be that DBVA have a “tool”, or “command” like: “Do you want to set all attributes to multiplicity=0…1? Yes/No”
[/quote]

Hi Jick,

Ok, I understand that they are some general cases that what I wrote does not apply, so the user must manually take this into account.

But, what about my feature suggestion? I think that this is still handy. I mean, this “new tool” can appear when right-click on a ORM Class, or ORM Component.

This way, if the user code checks for nullability in these attributes to MANUALLY determine that a ORM component is null, he/she has to manually set all the ORM component attributes to multiplicy=0…1. Having this “new tool” available will cut some more time to the design phase of a project.

Or am I wrong about this? :oops: (I have not tested it manually, but I think this would work)

Hi distansia,

Sorry, but I haven’t discuss your suggestion with our developers because I thought you will post more about that (you told me wait). Sorry about this. I have asked our developers to investigate if your suggestion is viable. Please wait.

Best regards,
Jick

Hello distansia,

Sorry for our late response. Our engineers further study your issue and seems it is not necessary to implement your suggestion since we are now will not change the nullable or ORM Component during synchronization. Would it be possible that you can give me more grounds about your suggestion? Looking forward to hear your reply.

Best regards,
Rain Wong