I have a situation that looks like the following :
Two entities Employee and EmployeeHty :
#Entity
#Table(name = "employee")
#Audited
#Data
#AllArgsConstructor
#NoArgsConstructor
public class Employee {
#Id
#GeneratedValue
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#ManyToOne
#JoinColumn(name = "employee_id")
private Employee employee;
}
#Entity
#Table(name = "employee_hty")
#Data
#AllArgsConstructor
#NoArgsConstructor
public class EmployeeHty {
#EmbeddedId
private HtyCompositePrimaryKey htyCompositePrimaryKey;
#Column(name = "revision_type")
private Integer revisionType;
#Column(name = "name")
private String name;
#ManyToOne
#JoinColumn(name = "employee_id")
private Employee employee;
}
#Embeddable
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#EqualsAndHashCode
public class HtyCompositePrimaryKey implements Serializable {
#Column(name = "id")
private Long id;
#ManyToOne
#JoinColumn(name = "revision_id")
private EmployeeAuditRevision auditRevision;
}
#Entity
#Table(name = "employee_audit_revision")
#Data
#AllArgsConstructor
#NoArgsConstructor
#RevisionEntity(EmployeeRevisionListener.class)
public class EmployeeAuditRevision {
#Id
#GeneratedValue
#RevisionNumber
#Column
private Long revisionId;
#RevisionTimestamp
#Column
private Date revisionDate;
#Column
private String userUid;
#ManyToOne
#JoinColumn(name = "user_id")
private User user;
}
An employee could have himself as boss. So i end up with this values in my database :
employee
id
name
employee_id
1
Jack
1
2
Melanie
null
employee_hty
id
revision_id
revision_type
name
employee_id
1
102
0
Jack
1
2
103
0
Melanie
null
revision types :
0 : created
1: updated
2: deleted
I want to delete manually Jack from the employee table and add a delete revision using SQL
INSERT INTO employee_hty VALUES (1, 104, 2, Jack, 1);
DELETE FROM employee WHERE id = 1;
Here is the situation i would like to be in :
employee
id
name
employee_id
2
Melanie
null
employee_hty
id
revision_id
revision_type
name
employee_id
1
104
2
Jack
1
1
102
0
Jack
1
2
103
0
Melanie
null
But since employee_hty has a foreign key constraint that link the column employee_id(table employee_hty) to the column id(table employee) it is not possible to do this. And i would like to have your thoughts on the matter.
Is deleting the foreign key constraint could be the solution ?
*NB: some details were omitted for the purpose of simplicity. *
Either remove the constraint or don’t populate the column for deletes
Related
The table was not being created for the following model despite following the correct procedure
Model
#AllArgsConstructor
#NoArgsConstructor
#Data
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
Integer pid;
String name;
String desc;
double price;
}
So I was creating an entity class for JPA where there was a field name desc. I was using MySQL database. But for some reason, I was getting the following error.
The model
#AllArgsConstructor
#NoArgsConstructor
#Data
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
Integer pid;
String name;
String desc;
double price;
}
Later I changed the field name and the whole thing was working. The ORM was automatically creating the table.
The updated model that works
#AllArgsConstructor
#NoArgsConstructor
#Data
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
Integer pid;
String name;
String description;
double price;
}
I want to use orderNumber in ProductRepository but I keep getting SQL error. I mapped both sides.
this is product entity.
#Entity
public class Product extends BaseEntity {
#Id
#GeneratedValue
#Column(name = "product_id")
private Long id;
#ManyToOne
#JoinColumn(name = "orderItem_id")
private OrderItem orderItem;
this is orderItem entity.
#Entity
public class OrderItem extends BaseEntity {
#Id
#GeneratedValue
#Column(name = "orderItem_id")
private Long id;
private String orderNumber
#OneToMany(mappedBy = "orderItem", cascade = CascadeType.ALL, orphanRemoval = true)
#Builder.Default
private List<Product> products = new ArrayList<Product>();
this is query in ProductRepository.
#Query(value = "SELECT * FROM OrderItem a, Product b WHERE a.orderItem_id = b.orderItem_id", nativeQuery = true)
Product findByOrderNumber(String orderNumber);
Alternatively, you can try query by a method as shown below, you don't need to use the #Query in this case.
ProductRepository
Product findByOrderItemOrderNumber(String orderNumber);
you can find more details here
I have #OneToMany and #ManyToOne relationship between parent and child entities.
#Entity
#Table(name = "parent")
public class Parent {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
#OneToMany(targetEntity=Measurement.class, mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
#PrimaryKeyJoinColumn
#JsonManagedReference
private List<Child> children = new ArrayList<>();
}
and I have child entity like this
#Entity
#Table(name = "child")
public class Child {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#ManyToOne(targetEntity=Parent.class, fetch = FetchType.LAZY)
#JoinColumn(name = "parent_id")
#JsonBackReference
private Parent parent;
After saving this data, the database looks like following,
Parent:
id
1
Child
id parent_id
2 1
my question is, why does the primary key of child is 2 and not 1? In the child table, it could have a primary key as 1 and foreign key reference to parent as 1. When I add one more parent, then the tables looks like this,
Parent:
id
1
3
Child
id parent_id
2 1
4 3
Am I doing something wrong or it is the expected behaviour?
The generation strategy #GeneratedValue(strategy = GenerationType.AUTO) will takes value from the default hibernate sequence, so the same sequence is used for all key generation.
When you are inserting the data, it inserts in the sequence like Parent then Child, as it is getting values from the same sequence generator, it will increase in sequence for all your table.
You need to use the GenerationType.IDENTITY strategy for your purpose.
In parent Parent
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
In child
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
I have this simplified JPA entities
#Entity
#Table(name = "students")
public class Student {
#Id
private Integer id;
private String name;
//getters, setters
}
#Entity
#Table(name = "averages")
public class Averages {
#Id
private Integer id;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "student_id", referencedColumnName = "id")
private Student student;
private float value;
//getters, setters
}
How I can write this query using JPA Specification and CriteriaBuilder?
SELECT students.id
FROM students,
averages
WHERE averages.student_id = students.id
GROUP BY students.id
HAVING AVG(averages.value) > 6
It should be something like:
select student.id
from Averages average
join average.student student
group by student.id
having avg(average.value)>6
i have no way of testing this
Edit: this is using EntityManager#createQuery(String)
#Entity
#Table(name = "project")
public class Project {
#Id
#Column(name = "project_id")
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#OneToOne
#JoinColumn(name = "idea_id", referencedColumnName = "idea_id")
#JsonIgnore
private Idea idea; .......}
And
#Entity
#Table(name = "idea")
public class Idea {
#Id
#Column(name = "idea_id")
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Size(max = 240)
#NotNull
private String description;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "project_id", referencedColumnName = "project_id")
private Project project; ..........}
What is wrong with my hibernate relationships in these two classes? This is example of relationship that I want to implement.
And this is actual tables that I get with these relationships:
Idea table:
And Project table:
How to get rid of null values in idea_id column in project table?