I've seen a lot of domains designed with circular reference. The image below describes a simple example for understand the question: A company has employees and departments and a department has employees, who belong to a department.
Logically, the model allows a employee who works for a company be related with a department of another company - of course, hypothetically, if business logic validation fails.
In some more complex cases, and according to the business rules, I donĀ“t see another way to model.
Is it acceptable?
Thanks in advance.
It is absolutely fine to have such kind of circular association.
Of course there are lots of pitfall that shoot your feet. However with extra cautious such kind of relationship is fact not always harmful.
Things that you need to pay extra attention includes:
Try to define the "owner" of the relationship. This is especially important if you are going to persist the entity
Make sure the owning relationships are not circular. For example, in your example, you can define Company owning the Company-Department and Company-Employee relationship, and Department owning the Department-Employee relationship
Make sure the relationship is consistent. For example, for the bi-directional relationship between Employee and Department, when you remove an Employee from a Department, make sure you remove the Department from Employee consistently.
Try to minimize the way to manage relationship. For example, instead of providing both Department#addEmployee(Employee) and Employee#addDepartment(Department), just provide Department#addEmployee(Employee). This should make your work of keeping consistency easier.
Still, if you can manage to make it uni-directional and non-circular, it is always easier to handle.
If you really want to avoid the situation you've described (where an employee "E" is associated with a department "D", but "D" and "E" are associated with different companies), you can try making your object model a tree, with no cycles:
Company --> Department --> Employee
There are trade-offs here. For example, this model doesn't directy handle Employees with no Department (although this could be papered over with a fake department like NoDepartment). This model may also require two "hops" to get from Employee to Company.
Related
I'm confused with designing a client software with database integration to what should be a member variable of the class or just a query to the database. Let me be specific with a trivial example:
If I have, lets say, a Student class, which has a list of "friends" that are Student objects. Should my software design have an ArrayList<Student> as a member variable of the Student class or should the Database deal with the relationship itself and the Student class doesn't account for those "friends"? How should a proper UML class-diagram be in this case?
This question is broader than you may think, as there are many ways to deal with it. Here some first ideas:
Let's start with a quick class diagram. The friendship between students is a many-to-many association.
In a database, a many-to-many association is usually implemented using an association table. So you'd have two tables: STUDENTS and FRIENDSHIPS with pairs of ids of befriended students:
To load a Student object from the database, you'd read the data in a STUDENTS row and use it to initialize your object. For the friendship, you'd have to read the relevant FRIENDSHIPS rows.
But how to use these tables in the application?
A first possibility would be to load each Student friend and insert it in the ArrayList<Student>. But each loaded student is like the first student and could have oneself friends that you'd have to load as well! You'd end up loading a lots of students, if not all, just for getting the single one you're interested in.
A second possibility would be use an ArrayList<StudentId> instead of an ArrayList<Student> and populate it. You'd then load the friends just in time, only when needed. But this would require some more important changes in your application.
A third possibility is not to expose an ArrayList. Not leaking the internals is always a good idea. Instead use a getter. So you'd load the friends only if student.getFriends() is called. This is a convenient approach, as you'd have a collection of friends at your disposal, but avoid being caught in a recursive loading of friends of friends.
In all the cases, you may be interested in using a repository object to get individual or collections of students, and encapsulate the database handling.
Advice: as said, there are many more options, the repository is one approach but there are also active records, table gateways and other approaches. To get a full overview, you may be interested in Martin Fowler's book Patterns of Enterprise Application Architecture.
You need a one-to-many relationship between Student and friends in both the relational database and the object model.
one to many
many to one
many to many
one to one
Need some more clarifications about them. Referred that in many sites but cant able to get the perfect definitions. thanks in advance
I explain you these conceptual data modeling relations on the example.
One to many (1:n) means one entity can work with more ones.
Example: One employer can hire more employees.
Many to one (n:1) works same as the one above from the different view.
One to one (1:1) means one entity can work only with the other one.
Example: Every employee can work only with one computer
Many to many (n:m) means there is a combination of relations between entities.
Example: Each customer belongs to more employees and one employee serves for one or more customers.
Usually in database systems there will be created a new table holding these relations in case of m:n.
Lets say I Have two entities with a one to one relationship, a person entity and a person detail entity. Are there any advantages to using cascade when I want to save as oppose to making a separate save for each entity?
Would it be different if it was not a one to one relationship?
To get started, one difference would be, if NOT cascade, there will be multiple network calls (N+1 effect). Based on size data, there are lot of other implications you need to worry about too.
I am going to use ElasticSearch for as the search repository in my application.
I have a few questions regarding what is best practice when it comes to organizing
objects in the search index when the objects have associations/relations to each other.
From what I know search indexes is a flat structure and doesn't work with the concept of
relations in the same way as a database.
Let say you have these domain objects:
Person:
- Has a one-to-many relationship with Car
Car:
- Is owned by one Person, many-to-one with Person
Department:
- Each Department have many People and each Person may belong to many Department, many-to-many
What would be the best way to store this in the search index? What are the options? For instance I want to find all the people belonging to a certain deparment, or all people where the car has more than 300 bhp.
I am using the Java client API if it matters.
Elastic search (or Lucene) isn't a relational database, so you would need to flatten your relationship model.
Try to model a view that gets this structure -
Car|Person|Department
This will give you all attributes required to lookup a car. This can be imported into a document for Car.
Similarly
Person|Department
will give you all information for a person. This will help you lookup a Person
Department can be a third document.
You can have multiple documents for each entity. But the relationship needs to be translated as a property of the entity.
I have a ManyToMany relationship between two classes, for instance class Customer and class Item. A customer can buy several items and an item can be bought by different customers. I need to store extra information in this relationship, for example the day when the item was bought. I wonder how is this usually modelled in JPA, cause I'm not sure how to express this in code. Do I have to create a new class to model all the attributes of the relationship and make a manyToMany relationship between the other classes or is a better way to do this?
Thanks
The recommended way is to create a new association class to store the needed attributes, and two one-to-many associations to the two parties involved.
I guess you will indeed have to create a new class for the relationship.
Like you said yourself, the correct way is to create a new class with the additional attributes.