I have this relationship in my database:
And I want to be able to create an order, that contains more products (as well more instances of the same product). Nevertheless I am able to have just one row in the order_has_product table for every single order_id. Moreover, I tried to load the data via lazyloading, but it won't work and it makes the whole app to run really slowly. Here are definitions of the relationship in my entities:
OrderEntity:
#ManyToMany(fetch = FetchType.LAZY)
#Cascade({org.hibernate.annotations.CascadeType.ALL})
#JoinTable(name = "order_has_product",
joinColumns = {#JoinColumn(name = "order_id", nullable = false, updatable = false)},
inverseJoinColumns = {#JoinColumn(name = "product_id", nullable = false, updatable = false)})
private List<ProductEntity> products;
ProductEntity:
#ManyToMany(fetch = FetchType.EAGER, mappedBy = "products")
private List<OrderEntity> orders;
Any idea how to fix lazyloading and to make it possible to have more products in order?
Related
I am new to Hibernate and now trying to understand cascade types. I know there mey be a lot of similiar questions, but let's say I have a many-to-many relationship between two tables: state and capital , which creates state_capital which stores two foreign keys of capital and state. If I were to remove a state entity or capital entity, it should remove only either state entity from state table or capital entity from capital table plus the corresponding records in state_capital. Currently If I try to remove a capital entity, it automatically removes the linked state and vice versa. Here's the relationship:
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
#JoinTable(name = "state_capital",
joinColumns = {
#JoinColumn(name = "id_state", referencedColumnName = "id_state",
nullable = false, updatable = false)},
inverseJoinColumns = {
#JoinColumn(name = "id_capital", referencedColumnName = "id_capital",
nullable = false, updatable = false)})
private Set<Capital> capitals = new HashSet<>();
#ManyToMany(mappedBy = "capitals", fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
private Set<State> states = new HashSet<>();
What should I do?
I have list that is mapped by a join table. What I need to do is make the combinations of "layouts" and 'views' not unique and also each with an index. What I thought of trying to do is making a Map<Integer, View> and somehow make the join table have a third column 'id'. What would happen is get the views of that layout and populate them with the id from the join table as a key in the map.
Any idea how to do that, or maybe a better idea for what I need?
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinTable(
name = "layout_view",
joinColumns = {#JoinColumn(name = "layout_id", nullable = false)},
inverseJoinColumns = {#JoinColumn(name = "view_id", nullable = false)}
)
private List<View> views;
What I imagine:
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinTable(
name = "layout_view",
joinColumns = {#JoinColumn(name = "layout_id", nullable = false)},
inverseJoinColumns = {#JoinColumn(name = "view_id", nullable = false)}
//some code for third column and populating it as keys
)
private Map<Integer, View> views;
You can already have multiple same views for a layout by using a List, as you're doing.
To preserve (and be able to change) the order, see OrderColumn and the Hibernate documentation about ordered lists.
The same documentation also describes how to implement your original idea with a map, if you really want that.
I found here a good article about designing the many-to-many schema with JPA.
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "student_subject", joinColumns = #JoinColumn(name = "student_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "subject_id", referencedColumnName = "id"))
private Set<Subject> subjects;
My question is, can I map a start schema, for example on JoinColumn I want to add multiple tables. It is possible?
I am trying to implement a delete function but all I get is this ORA-02292 ERROR:
Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-02292: Integritäts-Constraint (VDMA.FK892DE8B473F40868) verletzt - untergeordneter Datensatz gefunden
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:447)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:951)
I have an Entity (MainEntity) that has an n:m relationship with its child entity.
For example: A User can have multiple cars, each car can be driven by different users.
When a User is deleted, I want the associations between the User and the Car to be deleted as well. That´s why I thought I could do the following :
User Entity
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinTable(name = "user_car", joinColumns = {#JoinColumn(name = DATABASE_COLUMN_ID, nullable = false, updatable = false) }, inverseJoinColumns = {#JoinColumn(name = DATABASE_COLUMN_TYPE_ID,
nullable = true, updatable = false) })
private Set<UserCar> userCars;
Car Entity
#ManyToMany(fetch = FetchType.LAZY, mappedBy = "userCars")
private Set<User> users;
The result is :
The tables get created, the data gets persisted - everything works fine.
EXCEPT deleting entries: As soon as I try to delete a User and the User has a car (and therefore a user : car relationship) I do get the errors shown above.
If the user doesn´t have any cars I can delete him without any issues. So the problem must be the constraint in the USER_CAR table.
Clear userCars as well:
user.getUserCars().clear()
This will break the association between user and associated cars (it will delete the corresponding records from the junction table).
Also, you don't want CascadeType.ALL on many-to-many associations, because it implicitly contains CascadeType.REMOVE. Using it means that removal will be cascaded to cars as well, although there are other users who are associated with those cars.
Pls make sure you delete the child records, adding the orphanRemoval will help
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL,orphanRemoval=true)
#JoinTable(name = "user_car", joinColumns = {#JoinColumn(name = DATABASE_COLUMN_ID, nullable = false, updatable = false) }, inverseJoinColumns = {#JoinColumn(name = DATABASE_COLUMN_TYPE_ID,
nullable = true, updatable = false) })
private Set userCars;
This will delete all cars assoicated with a user.
My Empresa entity have 2 nested collections mapped that way:
#ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST})
#JoinTable(
name = "bandeiras_aceitas",
joinColumns = {#JoinColumn(name = "empresa_id", nullable = false)},
inverseJoinColumns = {#JoinColumn(name = "bandeira_id", nullable = false)})
private List<BandeiraCartao> bandeirasAceitas;
#OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL},
mappedBy = "empresa")
private List<HorarioAtendimento> horariosAtendimento;
I actually have 12 records on horariosAtendimento and only 1 record inside bandeirasAceitasfor the Empresa I am trying to fetch. But when I use my find method there are 12 records inside 'bandeirasAceitas', the problem is that the sql generated by jpa(hibernate) is duplicating the records like (number of records on horariosAtendimento* number of records on bandeirasAceitas). How can I solve this?