Hi there Pieter. Geode does not manage any relationships like 1:1, 1:M or even M:N.
Your observations, from your example, are correct. The child will be stored twice (once in the parent region and once in the child region). You've already reached a correct conclusion that the relationships are better maintained by referencing the parent/child via their respective keys. This of course has an additional overhead where you need to modify the parent every time you add/remove a child. Storing it in that manner has the benefit that your parent does not become a large object, as more and more child obj's are added. A "nice" feature would be to implicitly be able to define the relationships and then the underlying storage mechanism handles the normalized storage (like hibernate would do). But this feature does still require more thought. --Udo On Tue, Feb 6, 2018 at 1:15 AM, Pieter van Zyl <[email protected]> wrote: > Good day. > > We are investigating Geode to replace our current database solution. > > I would like to understand how Geode handles relationships. > > I hope I am posting to the right forum as this relates to fundamentals in > Geode but I am using the Spring Data Geode examples. > > Overall it seems to me that one-to-one or one-to-many relationships are > stored embedded into the "parent" region. > > If Parent has a list of Children then it seems that there are 2 options > in Geode: > > - Use id's that refer to the child entities. Child entities are then > stored in its own region. > - Direct reference to the Children. In JPA that would have been called > a one-to-many mapping. But this will be stored locally in the same region > as the Parent. > > I can see some examples using either id's or one-to-one or one-to-many > relationships here: > https://github.com/spring-projects/spring-gemfire-examples > > Specifically: spring-gemfire-examples-master/basic/persistence which uses > an Order that has an Address (one-to-one). Order also has a list to > LineItems that contains an id that represents the actual Product which is > an example of one-to-many. > > *I would like to confirm that as Geode is a key-value store that one would > need to represent one-to-one and one-to-many relationships using the id's > and then look them up to get the actual associated objects?* > > I did read this nice response here as well: > https://stackoverflow.com/questions/37908733/data-model- > design-guide-lines-with-geode/37931066#37931066 > > I just want to clearly understand using a example that speaks directly to > relationships. > > In the example below I can see that if I don't use id's that the child > objects get *stored twice*: in the Child region *as well also > local/embedded* with the Parent. > > /** > * This test shows that Geode store references to embedded one-to-one > entities locally to the parent object and then it can only see > * changes via the parent object and wont see changes made to the > child that are stored in other regions > */ > @Test > public void testChildAddedToOwnRegion() { > Parent parent = new Parent(2l, "Pvz"); > > Child child1 = new Child(5l, "Child1", parent); > childRepository.save(child1); > > Child child2 = new Child(6l, "Child2", parent); > childRepository.save(child2); > > Child child3 = new Child(7l, "Child3", parent); > childRepository.save(child3); > > parent.getChildren().add(child1); > parent.getChildren().add(child2); > parent.getChildren().add(child3); > > log.info("Parent: " + parent.getId()); > > parentRepository.save(parent); > > log.info("Parent: " + parent.getId()); > > Parent foundParent1 = parentRepository.findById(2l).get(); > log.info("foundParent1: " + foundParent1.getChildren().size()); > > List<Child> children = (List<Child>) childRepository.findAll(); > > log.info("Children found: " + children.size()); > Assert.assertEquals(3, children.size()); > > Child child = childRepository.findById(5l).get(); > Assert.assertNotNull(child); > Assert.assertEquals("Child1", child.getName()); > child.setName("Child5"); > childRepository.save(child); > > foundParent1 = parentRepository.findById(2l).get(); > List<Child> children1 = foundParent1.getChildren(); > > boolean found = false; > > for (Child ch : children1) { > > if (ch.getName().equals("Child5")) { > found = true; > } > log.info(ch.getName()); > } > Child childFound = childRepository.findById(5l).get(); > Assert.assertEquals("Child5", child.getName()); > Assert.assertFalse(found); > } > > Kindly > Pieter van Zyl > Lautus Solutions > South Africa >
