I have a oneToMany and ManyToOne mapping in my models:
class college
#OneToMany(fetch = FetchType.EAGER)
#JoinTable(name = "collegecource", joinColumns = #JoinColumn(name = "college", referencedColumnName = "college"), inverseJoinColumns = #JoinColumn(name = "cource", referencedColumnName = "cource"))
private Set<course> course;
In a relation able table collegecource i have one extra column isActive
I want to audit all the tables with create/update/delete.
I added #Audited in collegecource
#Audited
public class collegecource
When i try to create/update parent with relational data Audit working fine.
But when i try to delete relational data (Child data) it is not auditing.
Can You please help me.
If you want audit field, Annotation your field with #Audited.
(Child data)
Related
I am a JPA newbie and trying to understand #JoinTable annotation for Bidirectional OneToMany relationship b/w Project and Task Entities where Project can have multiple tasks.
I can use #JoinTable with Entity having #ManyToOne annotation, but when I am placing #JoinColumn on the other Entity having #OneToMany, I am not getting an option to specify "mappedBy" attribute on #ManyToOne annotation.
I would like to know why ?
I have tried placing #JoinTable annotation on both the entities but then Hibernate is itrying to insert two records in Join table
Project Entity :-
#Entity
#Data
public class Project {
#Id
#Column(name = "project_pk")
#GeneratedValue
private Long id;
#Column(name = "project_name")
private String name;
#OneToMany(mappedBy = "project", cascade = CascadeType.ALL)
List<Task> tasks;
}
Tasks Entity :-
#Entity
#Data
public class Task {
#Id
#GeneratedValue
#Column(name = "task_pk")
private Long id;
public Task() {
}
private String name;
#ManyToOne(cascade = CascadeType.ALL)
#JoinTable(name = "project_related_tasks",
inverseJoinColumns = #JoinColumn(name = "project_id", referencedColumnName = "project_pk"),
joinColumns = #JoinColumn(name = "task_id", referencedColumnName = "task_pk")
)
private Project project;
public Task(String name) {
this.name = name;
}
}
There are two ways to implement one-to-many relations:
Using a join table
Using a foreign key on the many-to-one side
mappedBy is used for the second way (using a foreign key). You don't have to specify mappedBy, if you want to use a join table.
Using a join table is not very good idea because you can't control that join table using Hibernate. For example you can't just add a record to a join table directly.
what is #JoinColumn and how it is used in Hibernate
I am new with Spring jpa and I am trying to perform the deletion operation on spring jpa many to many database. My database has user and drug. I can delete an user and deletes also the rows associated to it from user_drug table, I can delete a drug that has no linking to the user_drug table, but i cannot delete a drug that is also in the user_drug table.
I had a look on this page but the solutions from there do not work for me.. How to remove entity with ManyToMany relationship in JPA (and corresponding join table rows)?
Here is my code for User entity:
#ManyToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
#JoinTable(name = "user_drug",
joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "drug_id", referencedColumnName = "id"))
private Set<Drug> drugs = new HashSet<>();
Here is the code for Drug entity:
#ManyToMany(mappedBy = "drugs", fetch=FetchType.EAGER)
private Set<User> users = new HashSet<>();
And here is the delet method from DrugServiceImpl:
public void delete(Drug drug)
{
drug.getUsers().clear();
drugRepository.delete(drug);
}
I have also printed the size of drug.getUsers() after clear operation and it is 0. Why isn't it delete the drug from database?
I've tried in many ways.. Can someone please send some help?
that is how the cascade works it deletes from the relation table only and in the ManyToMany the relation table here is the user_drug table
and for this cases there are many solution one of them is deleting the drug in the same transaction of the deleting user
but another solution that will save the effort that you create the ManyToMany table as entity and put cascade on the drug object in the relation table
like this
But this in the User entity
#ManyToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="user")
private Set<UserDrug> drugs = new HashSet<>();
the UserDrug entity
public class UserDrug {
#ManyToOne
#JoinColumn(name="user_id")
User user;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name="drug_id")
Drug drug;
}
There's an Entity Class 'A' (supposed to be a Person),There's another Entity Class 'B' (supposed to be a Contract).
Entity 'A' has a relation #OneToMany to Class 'B' ( a person can sign alot of contracts). Entity 'B' also has a relation #OneToMany to Class 'A' (a contract can have many person signing it).
In this case, there's gonna be 2 JoinTable in database, but actually they both are somehow the same.
Is there anyway that i make them just using One JoinTable?
tnx for any help!
Looks like a #ManyToMany relation to me...
in class Person
#ManyToMany
#JoinTable(name="PERS_CONTRACTS")
public Set<Contract> getContracts() { return contracts; }
in class Contract
#ManyToMany(mappedBy="contracts")
public Set<Person> getSigners() { return signers; }
By using two #OneToMany there is no JoinTable.
you can use #ManyToMany like this
#ManyToMany
#JoinTable(
name="AB",
joinColumns=#JoinColumn(name="A_ID", referencedColumnName="ID"),
inverseJoinColumns=#JoinColumn(name="B_ID", referencedColumnName="ID"))
private List<B> bS;
Its a kind of Many to Many relationships. So it need just one junction table like person_contract in database. It will contains columns like:
Person_id
Contract_id
where both person_id & contract_id will be a composite unique key.
In hibernate it will be:
1. In Person table
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinTable(name = "person_contract ", joinColumns = {
#JoinColumn(name = "person_id", nullable = false, updatable = false) },
inverseJoinColumns = { #JoinColumn(name = "contract_id",
nullable = false, updatable = false) })
public Set<Contract> contracts;
In Contract table
#ManyToMany(fetch = FetchType.LAZY, mappedBy = "contracts")
public Set<Person> persons;
Situation:
You are complicating things here, the appropriate relationship between your Entities would be ManyToMany, because :
A person can sign many contracts.
And a contract can be signed by many persons.
And one JoinTable in this relationship is sufficient to give you all the requested details:
Who signed a given Contract.
Which Contracts have a Person signed.
Mapping:
So your mapping will be like this:
In your Person class:
#ManyToMany(mappedBy = "persons")
private Set<Contract> contracts= new HashSet<Contract>();
And in your Contract class:
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(
name = "PERSONS_CONTRACTS",
joinColumns = #JoinColumn(name = "CONTRACT_ID"),
inverseJoinColumns = #JoinColumn(name = "PERSON_ID")
)
private Set<Person> persons= new HashSet<Person>();
You can check this Hibernate Many-to-Many Association Annotations Example for further details.
In my DB I have three table USER, PERMISSION and a junction table USER_PERMISSIONS. As you can see I have clear many-to-many relationship.
And here is the question. I'm using a Hibernate. Is it possible to use only two classes, User and Permissions without creating a junction class UserPermissions? I mean can I use some kind of annotations to include my junction table USER_PERMISSIONS?
Yes you can. You need to use the #JoinTable and #JoinColumn annotation. Example below:
#Entity
#Table(name = "USER")
public class User {
#Id
#Column(name = "ID")
private Long id;
#ManyToMany
#JoinTable(name = "USER_PERMISSIONS",
joinColumns = #JoinColumn(name = "USER_ID", referencedColumnName = "ID"),
inverseJoinColumns = #JoinColumn(name = "PERM_ID", referencedColumnName = "ID"))
private Collection<Permissions> permissions;
A full working example with bidirectionaly many to many can be found in here http://en.wikibooks.org/wiki/Java_Persistence/ManyToMany
I have 2 entity classes (Class A and Class B) mapped to database tables. They are cascaded so that saving object of class A would reflect change in table concerned with Class B as well. Now I want to have a join table with primary key from Class B and primary key of new entity Class (Class C). I used standard hibernate #JoinTable annotation. But Join Table is not updated. Am I allowed to do so in hibernate?
Class A(Fieldvisit)
#OneToMany(mappedBy = "fieldVisitId")
#Cascade({CascadeType.SAVE_UPDATE,CascadeType.DELETE})
private Collection<Fieldvisitdetail> fieldvisitdetailCollection;
Class B(Fieldvisitdetail)
#JoinTable(name = "fieldvisitgeo",
joinColumns = {
#JoinColumn(name = "fieldVisitDetailId", referencedColumnName = "fieldVisitDetailId")},
inverseJoinColumns = {
#JoinColumn(name = "geoId", referencedColumnName = "geoId")})
#ManyToMany(mappedBy = "fieldvisitdetailCollection", cascade = CascadeType.ALL)
private Set<Geo> geoId=new HashSet<Geo>();
Class C (Geo)
#ManyToMany(cascade = CascadeType.ALL)
private Set<Fieldvisitdetail> fieldvisitdetailCollection= new HashSet<Fieldvisitdetail>();
Code for Saving to database
public void addFieldVisit(Fieldvisit visitReportInfo){
getSessionFactory().getCurrentSession().save(visitReportInfo);
}