Unidirectional M:M in Grails GORM - grails

Is it possible to have a Unidirectional M:M in Gorm?
e.g.
I have a Person object and I have TravelDestionion object.
A person can have been to many travel destination and some of these travel destinations have of course had many people. But, I never want to navigate from TravelDestination to Person.
Any tips?

You can technically just not access the other side, but Grails is too helpful in this regard. For example when you want to associate a new TravelDestination instance with a Person, you add it to the person's destinations collection (or whatever you named it). But to ensure that both sides are in sync with what the database will look like after calling save, Grails adds the Person to the TravelDestination's persons collection.
This can obviously be very expensive, e.g. with a User <-> Role relationship where 1,000,000 users have ROLE_USER, and one more gets that role, and that user becomes element #1,000,001 in the role's users collection, which gets loaded into memory by Hibernate to ensure uniqueness.
Check out this presentation where I discuss this and provide some performant options for reconfiguring the relationship without the potentially huge overhead of using collections to represent 1-many and many-many in GORM: http://www.infoq.com/presentations/GORM-Performance

Related

Node based properties on a relationship

I'm starting out with Neo4J to create a graph of users and their relationships. At the moment there is a single 'KNOWS' relationship between users i.e.
What I want to do now is specify properties on the relationship specifically for each of the users. For example, "interest" which indicates how much a user is interested in the other user. Can I specify this for each user on a single KNOWS relationship or would I need to create two relationships between the users and set the attribute on each of the relationships?
Any help would be appreciated.
Can I specify this (property: interest) for each user on a single KNOWS relationship or would I need to create two relationships between the users and set the attribute on each of the relationships?
You will need two relationships.
You could do it with one but then you have to keep two properties in the relationship and information about which property goes with which node. Much easier with two relationships.
From comment:
Can I keep them as bi-directional or would I need to use directional
in this case?
Relationships are always directional. It is only when you query that the concept of bi-directional appears, but that is not really bi-directional, it is without direction, e.g. (a)-[r]-(b). So you would use (a)-[r]->(b) and (b)-[r]->(a) or (a)<-[r]-(b). If you query with the direction, then you know how to apply the relationship property.
I typically do more of my work with Java as an embedded application instead of Cypher and it pays to use directional queries as it makes for less code to do the associations.
Note
Since your case is so simple, just try various methods and see what works. Remember to keep track of how long the quires take and if necessary add indexes. Also use the query profiling tool to make sure you are making effective queries.

ERD - Modelling can-be Relationship

I'm searching for a solution to model a "can-be" relationship.
E.g.: A User can be Special User.
Any suggestions?
Types for entities can be viewed (results) as one of the following two things:
Relationships
Fields
The types that results in fields are usually seen as functional redundancy, where different rows/records in a table can have the same type. For example, the sex/gender of a user, or access privileges or permission level from a user as well.
If, however, this field has attributes/properties, so we have a new entity. In this case, users would be relating to, for example, address, which may have the street name, house number, among other things. Or, in your case, if Special User has attributes/properties, we have a "Special Users" entity. The cardinality here depends on how many types a user can have, and that takes into account the problem context.
As you say that a user "can be", it means it "can not be" too. You could:
Set a nullable functional redundancy field in Users entity or,
Set an entity "Types of Users" and create a relationship N-N for
"Users". In this case, you would have an intermediate table that
would allow or not the connection between the two entities.
In both approaches you have the ability to add new types of users in the future without effort.
There is a third case, however, referred to as partitioning, where we have types and subtypes of entities. In this case, entities subtypes inherit fields of their super entities. I believe this is not your case here.
If you have any questions, please comment and I will answer.

Utility of "belongsTo" in manyToMany collection

can any one explain to me what's the utility of belongsTo in a ManyToMany relationship? for a OneToOne relationship it's obvious : if a record from the "OneToMany" side (the master table) is deleted the corresponding "ManyToOne" (the child table) are [CASCADE] deleted as well, but we can't apply the same thing in the case of ManyToMany relationShip since one child record may belongs to many records in the master table, Thank you
Like with a one-to-many, adding items to the one side involves calling the addTo*() method. The one side is responsible for managing the collection. It provides the means to add/remove items.
It is no different for a many-to-many; a side must manage the collection. The difference is that GORM/Hibernate has no way of knowing which side to use; either side could technically do it, but only one can. So you must decide by using belongsTo. That's why the Grails documentation says one side must own the relationship. In short, it's a Hibernate thing.

Grails how to set _idx field when INSERTing data from outside of the Grails application?

I have a scaffolded Grails application with two domains, Person and Course. Person belongs to Course, and Course hasMany Persons. I have modified show.gsp for Course to list all of the Persons associated with the selected Course.
To achieve this, Course.groovy contains the following line:
List persons = new ArrayList()
And, as a result, the "person" database table contains a persons_idx field. I frequently will be adding new data to the "person" table outside of my Grails application, from an external website.
When INSERTing new data, how to I figure out what to set persons_idx as?
I had originally used a SortedSet instead of an ArrayList for persons, since I care about sorting. But since I am sorting on Person.lastName, and there will always be multiple people with the same last name, then the list will exclude those persons who have the same last names as others. I wish there was another way...
Thanks.
Having two applications manipulate the same Database is a thing to avoid, when possible. Can your 2nd application instead call an action on the controlling app to add a Person to the Course with parameters passed to specify each? That way, only one app is writing to the DB, reducing caching, index, and sequence headaches.
You also state that Person belongsTo Course... so you create a new Person for "Bob Jenkins" for each course that he's in? This seems excessive. You should probably look into a ManyToMany for this.
Without moving to a service, unfortunately, you'd want to change the indices on some if not many of the rows for the children of the Course you're trying to add a Person to, as that index is the sorted index for all the Persons in the Course.
I would suggest going back to a "Set", and do your sorting in the app. Your other question about sorting already told you not to override compareTo to just check the last name. If I were you, I'd forget about overriding compareTo at all (except to check IDs, if you want), and just use the sort() method, passing in a closure that correctly sorts the objects.

Domain Driven Design: When to make an Aggregate Root?

I'm attempting to implement DDD for the first time with a ASP.NET MVC project and I'm struggling with a few things.
I have 2 related entities, a Company and a Supplier. My initial thought was that Company was an aggregate root and that Supplier was a value object for Company. So I have a Repository for company and none for Supplier.
But as I have started to build out my app, I ended up needing separate list, create, and update forms for the Supplier. The list was easy I could call Company.Suppliers, and create was horrible I could do Company.Suppliers.Add(supplier), but update is giving me a headache. Since I need just one entity and I can't exactly stick it in memory between forms, I ended up needing to refetch the company and all of the suppliers and find the one I needed to bind to it and again to modified it and persist it back to the db.
I really just needed to do a GetOne if I had a repository for Supplier. I could add some work arounds by adding a GetOneSupplier to my Company or CompanyRepository, but that seems junky.
So, I'm really wondering if it's actually a Value Object, and not a full domain entity itself.
tldr;
Is needing separate list/create/update view/pages a sign that an entity should be it's own root?
Based on your terminology I assume you are performing DDD based on Eric Evans' book. It sounds like you have already identified a problem with your initial go at modeling and you are right on.
You mention you thought of supplier as a Value Object... I suggest it is not. A Value Object is something primarily identified by its properties. For example, the date "September 30th, 2009" is a value object. Why? Because all date instances with a different month/day/year combo are different dates. All date instances with the same month/day/year combo are considered identical. We would never argue over swapping my "September 30th, 2009" for yours because they are the same :-)
An Entity on the other hand is primarily identified by its "ID". For example, bank accounts have IDs - they all have account numbers. If there are two accounts at a bank, each with $500, if their account numbers are different, so are they. Their properties (in this example, their balance) do not identify them or imply equality. I bet we would argue over swapping bank accounts even if their balances were the same :-)
So, in your example, I would consider a supplier an Entity, as I would presume each supplier is primarily identified by its ID rather than its properties. My own company shares its name with two others in the world - yet we are not all interchangeable.
I think your suggestion that if you need views for CRUDing an object then it is an Entity probably holds true as a rule of thumb, but you should focus more on what makes one object different from others: properties or ID.
Now as far as Aggregate Roots go, you want to focus on the lifecycle and access control of the objects. Consider that I have a blog with many posts each with many comments - where is/are the Aggregate Root(s)? Let's start with comments. Does it make sense to have a comment without a post? Would you create a comment, then go find a post and attach it to it? If you delete a post, would you keep its comments around? I suggest a post is an Aggregate Root with one "leaf" - comments. Now consider the blog itself - its relationship with its posts is similar to that between posts and comments. It too in my opinion is an Aggregate Root with one "leaf" - posts.
So in your example, is there a strong relationship between company and supplier whereby if you delete a company (I know... you probably only have one instance of company) you would also delete its suppliers? If you delete "Starbucks" (a coffee company in the US) do all its coffee bean suppliers cease to exist? This all depends on your domain and application, but I suggest more than likely neither of your Entities are Aggregate Roots, or perhaps a better way to think about them is that they are Aggregate Roots each with no "leaves" (nothing to aggregate). In other words, company does not control access to or control the lifecycle of suppliers. It simply has a one-to-many relationship with suppliers (or perhaps many-to-many).
This brings us to Repositories. A Repository is for storing and retrieving Aggregate Roots. You have two (technically they are not aggregating anything but its easier than saying "repositories store aggregate roots or entities that are not leaves in an aggregate"), therefore you need two Repositories. One for company and one for suppliers.
I hope this helps. Perhaps Eric Evans lurks around here and will tell me where I deviated from his paradigm.
Sounds like a no-brainer to me - Supplier should have its own repository. If there is any logical possibility that an entity could exist independently in the model then it should be a root entity, otherwise you'll just end up refactoring later on anyway, which is redundant work.
Root entities are always more flexible than value objects, despite the extra implementation work up front. I find that value objects in a model become rarer over time as the model evolves, and entities that remain value objects were usually the ones that you could logically constrain that way from day one.
If companies share suppliers then having supplier as a root entity removes data redundancy as well, as you do not duplicate the supplier definition per company but share the reference instead, and the association between Company and Supplier can be bi-directional as well, which may yield more benefits.

Resources