hello i am using spring boot, spring data jpa and postgres. I have the following scenario: I have 3 classes that make up a hierarchy person, student, and teacher, where student and teacher inherit from person.
#Entity
#Table(name = "person")
#Inheritance(strategy = InheritanceType.JOINED)
public class Person {
// Personal Data
#Id
#GeneratedValue(generator = "ID_GENERATOR_POOLED")
protected Long id;
#Column(length = 11, unique = true, nullable = false)
protected String idNumber;
}
#Entity
public class Student extends Person {}
#Entity
public class Teacher extends Person {}
the inheritance strategy is joined.
It is possible for a student to be a teacher. The problem is when inserting a teacher who is already a student or vice versa. Hibernate tries to save and it does so by inserting a new tuple in the person relation, generating repeated data and even an error because the idNumber is unique. How can i fix this? that is to say that if the person already exists, then only insert in the relationship student or teacher as the case may be
Related
I have sample workers table structure:
I have two type of workers: company workers and company branches workers. Type field can be only: 1 or 2. 1 - is company worker and 2 - is branch worker. How Now I can't write correct relationships method to get user company type (branch or company). Or I must create 2 tables (company_workers_table and company_branch_workers_table) for correctly write eloquent relationships?
You're looking for a polymorphic relationship:
https://laravel.com/docs/5.6/eloquent-relationships#polymorphic-relations
You want to set up your workers with two columns instead of just the type one, lets call this relation workplace. Your workers table would have workplace_id and workplace_type columns. The type columns holds the class of the related model (ie. App/Company) and your id column holds the ID of the related model, so the worker could be related to either a company or a company branch.
Your models will look something like this:
class Worker extends Model
{
public function workplace()
{
return $this->morphTo();
}
}
class Company extends Model
{
public function workers()
{
return $this->morphMany('App\Worker', 'workplace');
}
}
class Branch extends Model
{
public function workers()
{
return $this->morphMany('App\Worker', 'workplace');
}
}
I have this situation:
I have a table for Person (called persons). A person has a Name, an ID and a type (natural or juridical).
Then I have Organization, it of course is a juridical person that extends a Person and has specific fields like manager_id or employees.
Then I have an Authority which is a special government Organization, so in the end is also a Person and also has special required fields like decree_number (the number and year of the decree that constituted the Authority).
Then I have my database, where I have a table called persons.
My question is: should I create a new table for organizations and then another one for authorities? If not, how should I store the new fields that are required for Authorities or Organizations but not for a Persons?
I am doing this in a Laravel project, I could have:
/* Person.php */
class Person extends Model {
}
/* Organization.php */
class Organization extends Person {
protected $table = 'persons';
}
/* Authority.php */
class Authority extends Organization {
protected $table = 'persons';
}
Yes create another table but do not repeat the data which persons already has, you can just use relationships for that.
For instance, create a table called organizations which stores persons with organization level. The schema can be:
| person_id (FK to persons.id) | manager_id | other_fields |
Then another table for authorities which stores persons with authority level. The schema can be:
| person_id (FK to persons.id) | decree_number | other_fields |
Then in Laravel, just create a relationship, I'm assuming a one-to-one relationship here.
// Person.php
public function organizationProfile()
{
return $this->hasOne(Organization::class);
}
public function authorityProfile()
{
return $this->hasOne(Authority::class);
}
public function hasOrganization()
{
return $this->organizationProfile !== null;
}
public function hasAuthority()
{
return $this->authorityProfile !== null;
}
The design is like a Person can have profiles (which in your case is Organization and Authority). There could be other design but this is what I've thought of.
In summary, since Organization and Authority are both Persons with just another attribute, we just created another table to hold those attributes but not to repeat the attributes which are already present in Person. We will make use of relationships to determine if a Person is just a Person, an Organization or an Authority.
I have tried to make a logical data model, but I am not totally sure if it is modeled right. It is a very cut-down and basic model, but overall I want to know if it is modeled the way is should be.
Furthermore, how do I convert this into a class model in object oriented programming?
I guess I need:
Class Customer: int id, string name
Class Order: int id, string date, Customer object
Class Item: int id, string itemName, string item Desc
Class OrderItem: ?
For your data model, you don't need the relationship line between Orders and Items. You're using the junction table Order_Items to represent that many to many relationship.
As for the class models, you won't need a class to model the junction table. You can simply model it with a collection of Item in your Order class. The relationship between the Order and Item class is a composition relationship. You can think of it as: An Order has-a Item or an Order has-s collection of Item.
Here is how you can model the Order class in java.
public class Order {
private int id;
private Date date;
private Customer customer;
private List<Item> items; // you could use other collection types as well.
...
}
Edit:
Also for your many side of the relationships, you may consider using "one through many" line (crows foot with a line)" as opposed to "zero through many" (crows foot with circle). A order generally has atleast 1 item and atleast 1 customer. An order isn't an order without a customer or items.
I am new to grails and implementing one-to-one relationship in grails and trying to query on tables and not sure on how to represent one-to-one relationship in domain classes and query the results.
I have two tables
car(car_id number primary key,name varchar2(255))
engine(eng_id number primary key,name varchar2(255),car_id number (foreign key to car_id))
Domain Classes:
class Car {
..
static hasOne = [engine: Engine]
}
class Engine {
Car car
static belongsTo = [car : Car]
}
is the above one-to-ne relationship in domain class correct??
i need to query to get all the cars which have engines,should i use criteria query api or use HQL??
Any help appreciated.
class Engine {
//Car car
static belongsTo = [car : Car]
}
Just delete Car car and all be correct. For now u have 2 links to class Car in Engine
For a true one-to-one relationship use the hasOne property on the owning side e.g. Car:
class Car {
..
static hasOne = [engine: Engine]
}
class Engine {
Car car
static constraints = [
car unique: true
}
A good practice is to add a unique constrain on one side of the relationship. Click here to read the documentation.
If you have a set of tables in the database that strictly consist of a string description and an ID, what is the best way to load these via NHibernate?
So suppose I have a Sandwich class, and a sandwich has a meat, a cheese, and a vegetable, where those three things are lookup tables in the DB. It seems to be the most conformant to NHibernate philosophy to have
public class Meat { string name; int id; }
public class Cheese { string name; int id; }
public class Vegetable { string name; int id; }
public class Sandwich { Meat meat; Cheese cheese; Vegetable vegetable; }
But with a few dozen tables like this in the database, classes seem to proliferate quickly. Suppose I set it up like this:
public class NameAndID { string name; int id; }
public class Sandwich { NameAndID meat; NameAndID cheese; NameAndID vegetable; }
Is this feasible? How would it be implemented in Fluent NHibernate?
You'd need another column to determine the type. You could use an enum for that. Then all your lookups need to include that restriction....
CreateCriteria<NameAndID>.Add(Restrictions.Eq("ntype", E.Meat)
However, I'd prefer separate tables so you can have better foreign keys. Otherwise there is nothing in database constraints to stop you from making a sandwich that is simply 3 pieces of cheese.