2

Trying this again but with a slightly different approach. My previous thread was here Can anyone explain this one-to-one, one-to-many, many-to-one, many-to-many concept with respect to ORMs? but honestly I think it confused me more than it helped, especially when there seemed to be conflicting views even among the answers / commenters.

I'm not sure if my understanding is correct and I just lacked the vocabulary to express it, or if I have a serious hole somewhere that needs to be resolved with an explicit counter-example.

So I want to try this again with a more explicit example or two.

Example 1:

Let's say I defined two classes like so:

class A { 
    private String name;
    private List<B> listB;
}

class B {
    private String name;
}

Now in this example I have not said anything explicitly (in terms of annotations) about whether the relationships are one to one, one to many in either direction, or many to many. I am going solely from the cardinalities of the containers.

To my understanding, this is a one to many relationship from A to B and the ORM would map this like so:

enter image description here

Example 2:

Let's say I defined two classes like so:

class A { 
    private String name;
    private List<B> listB;
}

class B {
    private String name;
    private A referenceA;
}

I assume that this ends up with the same table mapping as Example 1.

Example 3:

Let's say I defined two classes like so:

class A { 
    private String name;
    private List<B> listB;
}

class B {
    private String name;
    private List<A> listA;
}

I assume this is a many-to-many relationship, and an ORM would map it like this:

enter image description here

My question is whether or not my understanding is correct and whether or not this sort of approach results in any ambiguities (and what an example of that might look like).

  • You should annotate the relations with the names of the relations. otherwise, its unclear. – Polygnome Aug 20 '16 at 20:08
  • @Polygnome I can't tell if you are trolling or not. This is sort of the entire reason behind me asking this question. If it is unclear, please show a counter-example of how it can be interpreted differently. – The 29th Saltshaker Aug 20 '16 at 20:36
  • You are assuming that the ORM would map your examples into tables where the relationship is mandatory in the ONE side. The code doesn't say that. The relationship is 0:M not 1:M. – Tulains Córdova Aug 20 '16 at 21:26
  • @TulainsCórdova What? Where do I imply it is mandatory? – The 29th Saltshaker Aug 20 '16 at 21:26
  • See @christophe 's answer. He also noticed it. – Tulains Córdova Aug 20 '16 at 21:27
1

If a ORM were to generate a table from the code you provide this would be the ER diagrams:

For code 1 and 2:

enter image description here

For code 3:

enter image description here

The code should have annotations that tell the ORM than the relationships are 1:M and not 0:M.

The red arrows were added by me to show yoy that the ONE side of the relationship is NOT mandatory, whereas in the diagram your provide it's mandatory, which is not inferable from the code you provide.

enter image description here

Hibernate, a popular, ORM may need you to add an annotation similar to this on class B to let it know that the relationship from B to A is mandatory (I don't use Hibernate, so anyone feel free to correct it):

@Column(name = "a_id", unique = false, nullable = false)
private A referenceA;
  • "The code should have annotations that tell the ORM than the relationships are 1:M and not 0:M" Why? How do you know when it is 1:M vs. 0:M? What would the classes have to look like to make it 1:M? – The 29th Saltshaker Aug 20 '16 at 21:52
  • @Basically there's nothing in your classes that FORCES you to have a non-null reference from B to A. So the ORM shouldn't map it to a relationship where you are FORCED to have a corresponding A before inserting a B. The model the ORM would generate, like your classes, would allow you to have stand-alone Bs, or stand-alone A_Bs. – Tulains Córdova Aug 20 '16 at 21:56
  • But if an object exists, doesn't that imply that it's already non-null to some degree? Or would I have to explicitly designate (somehow) in the class that the id field is non-null? I assumed this was default behavior or expected default behavior or something? – The 29th Saltshaker Aug 20 '16 at 21:58
  • @The29thSaltshaker A variable is not an object. It can be null. – Tulains Córdova Aug 20 '16 at 22:00
  • Are you referring to the possible case A someObject = null;? Or are you talking explicitly in terms of ID? – The 29th Saltshaker Aug 20 '16 at 22:06
1

For the examples 1 and 2 you are almost correct. Some comments:

  • In the class association of example 1 you can only navigate from A to B, but not backwards (in an UML class diagram you'd use an arrow for navigability)
  • The class association of example 2 is bidirectional: you can always navigate from A to B and vice versa (in an UML class diagram you'd use a line connecting the classes and either a bidirectional arrow or no arrow at all).
  • In the relational model, you don't have this subtle difference because relations are always bidirectional in an RDBMS. So in fact you can't represent exactly the example 1. You'll always be in the situation of example 2. The only difference that you would make is that your ORM code won't use the bidirectional navigation.
  • The table for B doesn't completely map your classes: according to your class model you could have a self-standing B not related to an A. You can't store such a reality in your table, unless either
    • you'd accept a_id could be null keeping your table model.
    • or you'd use 3 tables, you could then be even more accurate and guarantee a sequential ordering of the B's as in the A object's list: table A (id as primary key, name), table B (id as primary key, name) table AB (id_A and seqno primary key, id_B foreign key + unique constraint). This model would look like:
      enter image description here Note that this assumes that if you would have an item B with label "CHOCOLATE" that would appear in several As, there would be several instances of "CHOCOLATE" in B, each having a different id (because we're representing a one to many relationship, and not a many to many relationship).

For the example 3, the relational model doesn't accurately represent your class model:

  • Every A has a list of Bs, and every B has a list of As, but there is no guarantee that these are consistent (i.e. reciprocal). You could for example have an A with an empty list, but conversely having a B that uses this specific A in its list. Again the relation can be asymmetric in your class model, whereas it is always symmetric in your relational model.
  • You could of course decide that an invariant of your class model is that whenever a B is inserted in the list in an A, this A is reciprocally inserted in the list in B (and same for removal). In this case your model would be ok as it is (except if the order in each list would matter; you'd then have to ad some sequence numbers).
  • Another alternative could be to have two tables A_B and B_A in your relational model in order to represent the asymmetric situation.

In all this I assumed that your class example was in java, where the object's reference are stored in the list, so that they could be shared across several lists:

  • in example 1 and 2 I assumed that by construction you would not share the objects. If you'd allow sharing of B's (e.g. having one "CHOCOLATE" and refering to it in several lists) then you'd be in a unidirectional many to many relationship
  • would it be C++, you could make explicit if you share objects (using list of pointers to objects) or not (using list of objects)
  • this is why for data modeling, I'd prefer UML which is more expressive than the Entity/Relationship notation: you could represent the navigability constraints, and you could distinguish aggregation (e.g. sharing of elements/parts) from composition (owned elements/parts that are not shared).
  • Can you show me what the models SHOULD look like? – The 29th Saltshaker Aug 20 '16 at 21:29
  • @The29thSaltshaker the class model or the relational model ? – Christophe Aug 20 '16 at 21:32
  • Both -- I am trying to understand how things map – The 29th Saltshaker Aug 20 '16 at 21:33
  • @The29thSaltshaker I've tried to clarify explanation and adding one of the model. Hope this helps – Christophe Aug 20 '16 at 22:43
  • If UML is better then by all means -- I am just trying to learn this stuff. If UML is better then I am happy to go with UML – The 29th Saltshaker Aug 20 '16 at 22:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.