Hibernate/JPA mapping OneToOne relation / Heritage - jpa

I'm building my entities, I want to know 2 things please :
1) I have for example a class named "Order" and a class named "Order_Details" , I want to make them OneToOne on both side , how can I make it?? (Same thing with Order and Order_Validation).
2) I created a class "User" and Inherited many classes ("Client"/"Manager"/"Accountant" ...) "Manager" is related to other classes ("Order" for example ) so my question is in the "Order" table should I put a relation with "User" or "Manager"?? (I don't have an ID in )
Thank you

About #2...
It depends. Are you planning on having different tables for them? If this is the case, then you should put the relationship in Manager.

1) For your first question
Order Table
#OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "order")
private OrderDetail orderDetail;
Order_details Table. ( It will have a order_id column in it)
#OneToOne(optional = false)
#JoinColumn(name = "ORDER_ID")
private Order order;
2) Depending on what you want to do.
I would recommend going with USER table and USER_TYPE table. If a user will always belong to only on user type, then have a USER_TYPE_D key in USER table. If not have a one-to-many table like USER_TYPE_MAP table. Regarding the actions a user type can take, have a ROLES reference table and a separate table called USER_TYPE_ROLES which maps what role a user can play. So in JPA, you can User, UserType, Roles, UserTypeRoles etc and do a one-to-one or one-to-many mapping accordingly.

Related

Entity Framework - How to Insert to table with foreign keys without retrieving foreign table rows first

I'm having a hard time finding the exact answer to this question, so my apologies if this is redundant.
So I have 3 tables defined such that:
Person :PersonId, FirstName, LastName
Company: CompanyId, CompanyName
Order: OrderId, PersonId, CompanyId
On the Order table, there is a foreign key defined on the PersonId and CompanyId columns, thus, my Order entity class generated by EF has a navigation properties of type Person (not PersonId) and Company.
So, to insert into the Order table, I first need to query the person and company tables to get the person and company entities. Then I can construct the Order object using the Person and Company entities and save it to the db.
In my scenario, I am being passed a PersonId and CompanyId.
In classic SQL I would just do INSERT INTO Order Set (CompanyId, PersonId) - 1 database call. But with EF, I have to do 3 db calls. This seems like overkill.
Is there any way around this?
PS - I'm using EF 6. I know I could generate an expression and make it single call..but that would still yield two subselects.
You can just include foreign key properties in addition to the navigation properties and then set them using the ids you have. If you do this will not have to go to the database to get related entities for just a sake of setting the relationship.

JPA 2 one to many - how does JPA infer column information?

I have a JPA2 (Hibernate) application which uses a MySQL database with only two tables. One table is called "companies" and the other table is called "employees". Between the two tables there is a one-to-many ralationship (1 company has many employees). The foreign-key column in table "employees" is called "company_id".
In my JPA2 Application I use the following annotations:
In the entity class "Company" I have the following annotation
#OneToMany(cascade = CascadeType.ALL)
private Collection<Employee> employees;
and in class Employee
#ManyToOne
private Company company;
How does JPA know what column it should use to determine all employees of a company. The annotations do not hold this information, but the application works.
Thank you
The ManyToOne side is missing the optional JoinColumn annotation, which in turn has the optional name attribute defaulting to:
The concatenation of the following: the name of the referencing relationship property or field of the referencing entity or embeddable class; "(underscore)"; the name of the referenced primary key column. If there is no such referencing relationship property or field in the entity, or if the join is for an element collection, the join column name is formed as the concatenation of the following: the name of the entity; "(underscore)"; the name of the referenced primary key column.
On the other side of the relationship, the OneToMany side, it's missing the mappedBy attribute (it should be equal to the name of the field that owns the relationship, in your case "company"). Javadoc says that this attribute is required unless the relationship is unidirectional, so there are chances that the JPA implementation you are using is assuming the relationship is unidirectional.

JPA 2 #JoinTable with keygeneration

Is there a way in JPA 2 to use a #JoinTable to generate a UUID key for the id of the row? I do not want to create new entity for this table (even if that would solve the problem) and I do not want to create it from the DB.
#ManyToMany
#JoinTable(name="Exams_Questions", schema="relation",
joinColumns = #JoinColumn(name="examId", referencedColumnName="id"),
inverseJoinColumns = #JoinColumn(name="questionId", referencedColumnName = "id"))
private List<Question> questions = new ArrayList<Question>();
db table
CREATE TABLE [relation].[Exams_Questions](
[id] [uniqueidentifier] PRIMARY KEY NOT NULL,
[examId] [uniqueidentifier] NOT NULL,
[questionId] [uniqueidentifier] NOT NULL,
Not sure exactly what the question is, but let me try a response.
For your first sentence alone, I would say "Yes" and "Possibly":
You'll need a separate #Entity class for the Question, and in that class you'd specify the mapping for id.
There is no way using spec JPA to specify auto-generation of a UUID value for a column. There are ways using OpenJPA and Hibernate. EclipseLink will allow you to create a custom generator for this purpose, and their example is, in fact, for a UUID.
If you'd like to expose properties of the join-table OR otherwise have JPA manage them (i.e. the id on the Exams_Questions table), then see this external link (found on this answer). You'll end up with #OneToMany relations from Exam/Question entities to the join table, and #ManyToOne relations from the join table to Exam/Question entities.
Exposing the join table as an entity will let you manage a separate key (uuid). If you don't need the uuid primary key, then don't do this - it's not necessary to solve the problem, as the examId/questionId combination is unique.

JPA SortedMap mapping - avoid two columns with keys

I have two classes, CalculatedValue and Price. Price has map of CalculatedValue. Each CalculableValue instance has name, value and couple of other fields.
Here is mapping I use to describe a dependency between Price and the CV:
#OneToMany(
cascade = CascadeType.ALL,
fetch = FetchType.EAGER
)
#JoinColumn(name = "priceId")
private Map<String, CalculatedValue> calculatedValues =
new TreeMap<String, CalculatedValue>();
No join table, just mapping by priceId column which refers to Price unique Id.
Here is how generated table looks like:
CREATE TABLE PUBLIC.CALCULATEDVALUE (
UNIQUEID BIGINT NOT NULL,
KEY VARCHAR(2147483647) NOT NULL,
PRICEID BIGINT,
VALUE DOUBLE NOT NULL,
CALCULATEDVALUES_KEY VARCHAR(2147483647),
PRIMARY KEY (UNIQUEID)
);
ALTER TABLE PUBLIC.CALCULATEDVALUE
ADD FOREIGN KEY (PRICEID)
REFERENCES TEST.PUBLIC.PRICE (UNIQUEID);
Everything is working, but I want to know if it possible to to this:
Avoid automatic "CALCULATEDVALUES_KEY" column creation. I already have this value stored in KEY column and it would be nice to avoid duplication and somehow give a hint to JPA.
Trigger cascade delete of calculable value for each removed price (in case I'm running SQL delete statement)
Will such mapping work in case I'll use Date as a key? Not for this particular field, but for a bunch of other ones it will be useful. Assuming the same OneToMany relationship.
Thank you in advance!
PS. I'm using latest version of EclipseLink & H2 as database.
PPS. Didn't want to store the calculable values in array since I need to often find it buy key in Java.
For info on Maps see,
http://en.wikibooks.org/wiki/Java_Persistence/OneToMany
and,
http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Maps
and,
http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_cascadeondelete.htm#CIABIIEB
A few issues:
EclipseLink will use Hashtable by default for Map, if you want it to use TreeMap you need to define the field as TreeMap.
Do not give a #JoinColumn on a #OneToMany, this is only supported for advanced unidirectional #OneToMany, a normal #OneToMany should use a mappedBy and have an inverse #ManyToOne in the target entity. (this will fix your issue of the duplicate foreign key).
You need to specify the #MapKey for a map, otherwise it defaults to the id, which seems to be an integer here, not a string.
You can use #CascadeOnDelete in EclipseLink to cascade a delete on the database.

How to do many-to-many relation between the same entity

I have an Employee entity class with (Id,Name,EmployeeType). EmployeeType entity (Id, Description) where Description can be either REGULAR/MANAGER.
I am confused on how to map Employees who are of type REGULAR to their corresponding MANAGER type Employees. Should I just add an extra field to the Employee entity itself so that it now becomes (Id, Name, EmployeeType, ManagerEmployeeId)? Or should I instead have a lookup table Employee_Manager (Id, RegularEmployeeId, ManagerEmployeeId)?
I am considering going with the Employee_Manager lookup table and am not sure how that entity class would look like. The following below is what comes to my mind. Am I on the right track here?
#Entity
#Table(name="EMPLOYEE")
public class Employee{
#Id
int id;
#Column(name="NAME")
String name;
#ManyToMany(mappedBy = "regularEmployee")
Collection<Employee> regularEmployee
#ManyToMany
Collection<Employee> managerEmployee;
}
ps. I am using JPA with Hibernate as the persistence provider.
If you're trying to have an employee have exactly one manager, then first of all you're doing a many-to-one relation (not many-to-many) and having the ManagerEmployeeID in the table as a foreign key reference to the same table is just fine.
Use a lookup table if you want to allow an employee to potentially have more than one managerial-type role. You can also use this if you want to assign a particular "role" to these manager-type people:
create table Supervisors (
eid int,
sid int,
role varchar(16)
);
Then you could use role for "Supervisor" vs "Manager" vs "Slavedriver" vs who knows what.
Sorry, I don't know any JPA/Hibernate, so the concepts (and pseudo-SQL) is the best I can give you.
Hope that helps a bit.