-
Notifications
You must be signed in to change notification settings - Fork 234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Querying "OneToMany" related data returns "null" #158
Comments
Hi, I did make some changes on the "schema", namely changed all the names to "lower case" only, I had "CamelCased" names, which I think was generating trouble... Now I am able to get some related elements on OneToMany... however this is still not working for the case of Domain OneToMany ServiceTypes... These are the class entities I have (Domain OneToMany ServiceTypes OneToMany ClassificationProperties OneToMany ClassificationPropertiesValues): Domains:
ServiceTypes:
ClassificationProperties:
ClassificationPropertiesValues:
I am only able to get "ClassificationProperties" from "ServiceTypes"... all the other OneToMany do not work... I am not able to get ServiceTypes from Domains, and ClassificationPropertiesValues from ClassificationProperties (which I get from ServiceTypes). No idea why is this happening. My persistence.xml looks like this:
Thank you in advance for any guidelines to solve this problem... |
One problem which i am able to see is:
in ServiceTypes entity. As Domains entity also holds reference to ServiceTypes with column of same name:
Looks problematic to me. -Vivek |
Hi Vivek, You are right, I was setting the "redundant" fields on my persistence classes... They do exist on Cassandra but we only need one in the OneToMany fields... The corrections I did lead to the behavior expected in most of the times, namely: get ClassificaitionPropertiesValues from ClassificationProperties, and ClassificationProperties from ServiceTypes.... However, I cannot get the ServiceTypes from Domains... Please find bellow the new entity classes (with the commented fields where I did change) and also find the Cassandra table structures): Domains (Cassandra: domain | domain_description):
ServiceTypes(Cassandra: service_id | count | domain | instance_property | service_description):
ClassificationProperties (Cassandra: prop_id | classification_property | service_id):
ClassificationPropertiesValues (Cassandra: prop_value_id | classification_property_value | prop_id):
Cheers! |
Just an update on declaring "repeated" fields... it can be done if instead of using "@joincolumn" we use "mappedBy", as in the following:
However, I still have the problem referred in the previous comment... |
Let me try at my end. I will update you on this. -Vivek |
Hi emgsilva , Domains:-
ServiceTypes:-
ClassificationProperties:-
ClassificationPropertiesValues:-
test:-
persistence-unit:-
Only one difference in persistence unit is
for creating keyspace and column family. Cheers |
Hi Kuldeep, Thank you for taking the time to test it in depth... I have just performed the same test myself... and again I get the very same behavior... cannot get the ServiceTypes from the Domains (Assert.assertNotNull(foundDomain.getServiceTypes()); fails!).... If I skip that (get the services directly) all the other tests working fine (I also synchronized the persistence.xml). Just to make sure everything we have the exact same setup here are my cqlsh CQL3 (cqlsh --cql3) scripts to create the tables in Cassandra: Domains:
ServiceTypes:
ClassificationProperties:
ClassificationPropertiesValues:
Please let me know if you see any problem with this! Thank you for your assistance! Cheers! Eduardo |
Hi Eduardo, I would suggest, if you could try it at your end in case if it works for you. -Vivek |
Hi Vivek, Indeed, that seems to be the problem (I am still using Cassandra 1.1.6, probably need to update to the latest version). I decided to use CQL3 because in some other tables (and keyspaces) where I needed to use "composite keys", so I decided to stick around and use "cqlsh --cql3" for creating all my new cassandra keyspaces/tables. These are the tests I did, following your advise:
In order to make sure my "workflow" is working OK (I normally create the schemas beforehand on cqlsh or cassandra-cli), I used "cassandra-cli" and create all the tables "manually". Then I performed the test from Kuldeep and also mine (previously failing) are now working fine! I will proceed with my developments, it may be that I need to use composite keys very soon, and I will see how it works, however I am not sure I can make those in "cassandra-cli"... any thoughts on this? Thank you again for the always quick feedback and support! Cheers, Eduardo |
Hi Eduardo, Thanks |
Hi Kuldeep, Indeed, as you refer in your link, to enable composite keys I need to use cqlsh --cql3... this is what I was already doing on another table (it is a single table with a composite key). Hopefully I will not get this "weird" behavior I was getting in this issue if I need to create new tables with composite keys with relations with other tables. I think I will also upgrade to the new version of cassandra, which according to Vivek seems to not have these issues anymore... I will let you know if something pops up... but this issue is now closed! Thanks again for all the support and keep up with the great work! Cheers, Eduardo |
Hi Kuldeep/Eduardo, Composite/compound primary key support is enabled via CQL only. So Kundera simply translates everything in CQL format(bypassing thrift API). But for others it will still go by thrift way. I have discussed this issue with Jonathan(cofounder of datastax) and it has been promised to be released with cassandra 1.2. However while upgrading Kundera for cassandra 1.2 APIs. We did encounter some issues and have posted them on user group. Still waiting for some concrete answers on that. Rest is fine. So, i would suggest, to use cqlsh for fetching data over non-composite column family, but not manage(insert/delete/update). Sharing my understanding with you guys 👍 -Vivek |
Hi Vivek, I can see this is still these developments (on Cassandra) are still being matured... but it is important to provide some guidelines (maybe on the wiki - troubleshooting), so whenever one comes across to these problems can get some quick reference to overcome it. I understand that this is not a Kundera problem, but at a given point one cannot trace back where the problem is taking place, in my case I still do not understand why it working between some tables (relations) and the other not... Thank you for sharing your understanding Vivek, it is very good to keep on learning these details! Cheers, Eduardo |
Hi Vivek, Just a quick follow-up... at this moment I am implementing a mix of tables with composite keys and other (related tables) with non-composite keys... It seems to me the best way to implement my requirements. I did a very quick test implementing such a mix and got problems, namely I am getting this message (which I suppose does have something to do with the handling you refer above - through thrift if it is non-composite):
I get this error when using Kundera
which automatically generated the tables that have "composite keys" (the tables without composite keys are not generated)... The same took place when I generated the tables manually via cassandra-cli and cqlsh... Is it impossible to get it running (Kundera and Cassandra) at the moment with a mix of (related - OneToMany) tables with composite keys and tables without composite keys? (I am still using cassandra 1.1.6... but you said it is still a problem with 1.2)... I may opt to implement only "non" composite key tables but it would be much more elegant (an I suppose faster - given that I would not need to implement secondary indexes) with composite keys... EDIT: quick update, testing only with two Tables with composite keys (created from cqlsh --cql3, I removed the kundera.ddl.auto.prepare), I do have more tables without composite keys but I wanted to test this first... When I add values to one table alone and commit it works fine (I can see the values are stored), however when I add a values to the related table (OneToMany), I get an error message:
These are the persistency classes:
(sorry for the very long post... I wanted to add as much info as I could gather). Cheers! Eduardo |
I will have a look on OneToMany relationship b/w entities referring to composite keys. On Mixing thrift and CQL part, as you have encountered same happens even from cassandra-cli and cql. I would suggest to try that with cassandra 1.2(There are changes are large level around such handling). Issues which i have been talking about in 1.2 are bit different. -Vivek |
Hi Eduardo, So valid scenarios are:
hope it helps! -Vivek |
Hi Vivek, Thank you for the insights... You reasoning sounds right, but I am not sure if I understand it fully... I have the following two questions: 1: I agree with you reasoning on the 1-M relations between two tables with compositeKeys, namely the Key of table A should be available in table B (as foreign key). Can't we use a non-key field (granting it has a unique value) to be the "JoinColumn" between table A and table B (you can see in my declaration above as "instance_id")? Is this reasoning wrong? 2: I am not sure I agree that if table A has a composite key it cannot have 1-M relations with another table (with or without composite key, from what I understand of your comment)... Can't we use the values/metadata of the EmbeddedId of table A and map them to columns of table B? I cannot see how could we do that, I suppose we cannot use "JoinColumn" or "mappedBy", these are defined by one column only... I understand Hibernate uses some annotations to do that (1-M relations) on the M-1 side, for example I have this one another MySQL DB (got this via reveng the DB):
The point of my design using composite keys is trying to identify an element on table A "quickly" (by using a compositeKey - and no secondary indexes)... then "get" all the related elements on other table(s) B (1-M relations). I could live without "composite keys" on tables B... If this design is problematic I may opt for non-composite keys and use "secondary indexes", but this would not be so performant, from my understanding. I would like to see your points on these issues... I will be performing some further testing and come back soon. Cheers, Eduardo |
I am not sure, but as per JPA specification, it has to be in foreign key relationship. That's what we follow. Also on composite key column family we cannot hold secondary indexes. So concept of holding unique key will not possible.
The point of my design using composite keys is trying to identify an element on table A "quickly" (by using a compositeKey - and no secondary indexes)... then "get" all the related elements on other table(s) B (1-M relations). I could live without "composite keys" on tables B... If this design is problematic I may opt for non-composite keys and use "secondary indexes", but this would not be so performant, from my understanding.
|
Thank you for the feedback. I still need to think further about this... but I do not seem to be able to implement a {B (1-M) A, A (M-1) B}, this does not make sense for my DB as I want B to hold different counts/occurrences for the same A (so the same B cannot be part of Many A). Maybe I am not yet seeing clearly what you meant with your suggestion... I clearly need {A (1-M) B}... however, if I do use a CompositeKey on A, I will then not be able to get it working with B (even if B is not compositeKey) from what I get from your feedback... I could implement A with a compositeKey of 2 key-elements, however the ideal situation in my case would be to have 2 key-elements. What I am thinking about to do is to create a new table to work as a kind of index (IndexTable) with a composite key (with the 3-keys I have to identify my "ServiceInstance"), then a unique ID.... I then use this ID as a single key on my ServiceInstance table, which can have 1-M mappings to the other tables... This means this IndexTable does not have any JPA relation with the ServiceInstance table, I have to "persist" the IndexTable.ID on the application. This may not be very orthodox, but I have the feeling it can be a good decision in terms of performance. What do you think? (I have the feeling this kind of design decisions are made on NoSQL DB... I am just starting, coming from RDBMs, so still learning, but need to learn fast :), and may be even thinking wrongly). Cheers, Eduardo |
I guess that should work for you. That should even meet purpose/reason behind composite key and still you can exploit you IndexTable for other functional use cases. At the same time, ServiceInstance and associated entity should meet your requirement as well. Only catch is it is dependent on IndexTable for it's row key value. In terms of performance, if you deploying cassandra on single node, there is absolutly no problem. But on multi node deployment, there are some other factors like partition scheme and node selection strategy plays a vital role as well. You may need to build in some intelligence in order to achieve data co location with such functional aspects. So if i am getting your requirement correctly, IndexTable will hold a unique key which is essentially row key for ServiceInstance. So while finiding data you need to fetch this unique key first from IndexTable and then perform search over ServiceInstance and associate entity, correct? I think it should be good to go. And still you could fetch a single column from IndexTable(i.e. unique id for ServiceInstance), so performance should not be such bottleneck. Also Kundera's first level cache should help you out to reduce repititive I/O calls! Hope it helps, Cheers, |
hi Vivek, Thank you for your feedback... you completely got my reasoning and it is good to hear that it sound reasonable :) Indeed, whenever I get multi-node the partitioning may be tricky (I am still trying to see if I get 2/3 keys compositeKey, it looks like 3 would be the best). But I do think this will indeed some optimization in the future when I move to a multi-node. I will be implementing this solution (create the IndexTable with cqlsh --cql3, and all the others withe cassandra-cli, like the solution taken to solve in the original issue of this thread)... It should all work fine, I will "bother you" again if something pops up... Again, thank you for the quick support and very detailed feedback! Cheers, Eduardo |
Great . Do let us know, if you face any issue. Kundera 2.3 is releasing tomorrow :) will post an update on kundera-discuss group. -Vivek |
Hi,
I am having problems retrieving all the related elements from a related table in a "OneToMany" relation (one Domain has Many ServiceTypes):
I am able to query the Domain by the "domainID" (Domains domain = em.find(Domain.class, domainID);) but when I try to get the related "ServiceTypes" (domain.getServiceTypes()) I get a "null" (although I am sure I have two "ServiceTypes" as part of the domain in the DB - with the "domainID" field)....
I am using: Kundera 2.2, Cassandra 1.1.6.
The text was updated successfully, but these errors were encountered: