You are missing the concept of Owning
entity. The mappedBy
annotation in Employer
and DeliveryAgent
defines the owning entity of the relationship as the EmployerDeliveryAgent
entity. Since you have defined all the entities and repositories yourself you have to manage them yourself as well.
Setting relationship properties in a non-owing entity doesn't do any persistence. As a result those properties are for query only. Setting deliveryAgentAssoc
or employerAssoc
doesn't do anything for JPA.
Also, the Embedded
pattern of ManyToMany
is newer and generally works better.
Finally, use a Set
unless you really think you have a reason to have an ordered List
for OneToMany
relations. Having multiple List
relations in an entity causes JPA problems. Also, do not use Java primitive types in JPA based packages since that leads to problems and confusion.
Print out the SQL statements when writing your code so you can see what is going on. This is important because JPA will do lots of lazy fetches when you are not looking and if you don't understand that is happening and manage them you end up with errors and problems you don't understand. Ask any JPA coder about the dreaded LazyInitializationException
.
So, as a suggested result:
@Entity
public class Employer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy="employer")
private Set<EmployerDeliveryAgent> deliveryAgentAssoc;
@Entity
public class DeliveryAgent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy="deliveryAgent")
private Set<EmployerDeliveryAgent> employerAssoc;
@Entity
@ToString
public class EmployerDeliveryAgent {
@EmbeddedId
private EmployerDeliveryAgentId id = new EmployerDeliveryAgentId();
@ManyToOne
@MapsId("employerId")
private Employer employer;
@ManyToOne
@MapsId("deliveryAgentId")
private DeliveryAgent deliveryAgent;
@Column(name = "is_project_lead")
private Boolean isProjectLead;
And your ID class:
@Embeddable
public class EmployerDeliveryAgentId implements Serializable {
private static final long serialVersionUID = 1L;
private Long employerId;
private Long deliveryAgentId;
And to use it:
Employer emp1 = new Employer();
employerRepo.save(emp1);
DeliveryAgent da1 = new DeliveryAgent();
deliveryAgentRepo.save(da1);
EmployerDeliveryAgent eda1 = new EmployerDeliveryAgent();
eda1.setEmployer(emp1);
eda1.setDeliveryAgent(da1);
eda1.setProjectLead(false);
employerDeliveryAgentRepo.save(eda1);
DeliveryAgent da2 = new DeliveryAgent();
deliveryAgentRepo.save(da2);
EmployerDeliveryAgent eda2 = new EmployerDeliveryAgent();
eda2.setEmployer(emp1);
eda2.setDeliveryAgent(da2);
eda2.setProjectLead(true);
employerDeliveryAgentRepo.save(eda2);
employerDeliveryAgentRepo.findAll().forEach(System.out::println);
EmployerDeliveryAgent edaex = new EmployerDeliveryAgent();
edaex.setEmployer(emp1);
employerDeliveryAgentRepo.findAll(Example.of(edaex)).forEach(System.out::println);
employerDeliveryAgentRepo.deleteAll( employerDeliveryAgentRepo.findAll(Example.of(edaex)));
which results in the following Log outputs:
Hibernate: drop table delivery_agent if exists
Hibernate: drop table employer if exists
Hibernate: drop table employer_delivery_agent if exists
Hibernate: create table delivery_agent (id bigint generated by default as identity, primary key (id))
Hibernate: create table employer (id bigint generated by default as identity, primary key (id))
Hibernate: create table employer_delivery_agent (is_project_lead boolean, delivery_agent_id bigint not null, employer_id bigint not null, primary key (delivery_agent_id, employer_id))
Hibernate: alter table employer_delivery_agent add constraint FKqfdjch3412029revbsh103okx foreign key (delivery_agent_id) references delivery_agent
Hibernate: alter table employer_delivery_agent add constraint FKc3djdeycywdtbpn4muakrhhtq foreign key (employer_id) references employer
2020-05-05 10:56:36.200 INFO 7588 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2020-05-05 10:56:36.204 INFO 7588 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2020-05-05 10:56:36.403 INFO 7588 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 1.455 seconds (JVM running for 1.821)
Hibernate: insert into employer (id) values (null)
Hibernate: insert into delivery_agent (id) values (null)
Hibernate: select employerde0_.delivery_agent_id as delivery2_2_0_, employerde0_.employer_id as employer3_2_0_, employerde0_.is_project_lead as is_proje1_2_0_ from employer_delivery_agent employerde0_ where employerde0_.delivery_agent_id=? and employerde0_.employer_id=?
Hibernate: select deliveryag0_.id as id1_0_0_ from delivery_agent deliveryag0_ where deliveryag0_.id=?
Hibernate: select employer0_.id as id1_1_0_ from employer employer0_ where employer0_.id=?
Hibernate: insert into employer_delivery_agent (is_project_lead, delivery_agent_id, employer_id) values (?, ?, ?)
Hibernate: insert into delivery_agent (id) values (null)
Hibernate: select employerde0_.delivery_agent_id as delivery2_2_0_, employerde0_.employer_id as employer3_2_0_, employerde0_.is_project_lead as is_proje1_2_0_ from employer_delivery_agent employerde0_ where employerde0_.delivery_agent_id=? and employerde0_.employer_id=?
Hibernate: select deliveryag0_.id as id1_0_0_ from delivery_agent deliveryag0_ where deliveryag0_.id=?
Hibernate: select employer0_.id as id1_1_0_ from employer employer0_ where employer0_.id=?
Hibernate: insert into employer_delivery_agent (is_project_lead, delivery_agent_id, employer_id) values (?, ?, ?)
Hibernate: select employerde0_.delivery_agent_id as delivery2_2_, employerde0_.employer_id as employer3_2_, employerde0_.is_project_lead as is_proje1_2_ from employer_delivery_agent employerde0_
Hibernate: select deliveryag0_.id as id1_0_0_ from delivery_agent deliveryag0_ where deliveryag0_.id=?
Hibernate: select employer0_.id as id1_1_0_ from employer employer0_ where employer0_.id=?
Hibernate: select deliveryag0_.id as id1_0_0_ from delivery_agent deliveryag0_ where deliveryag0_.id=?
EmployerDeliveryAgent(id=com.example.demo.EmployerDeliveryAgentId@3e1, employer=com.example.demo.Employer@52ae997b, deliveryAgent=com.example.demo.DeliveryAgent@32f32623, isProjectLead=false)
EmployerDeliveryAgent(id=com.example.demo.EmployerDeliveryAgentId@400, employer=com.example.demo.Employer@52ae997b, deliveryAgent=com.example.demo.DeliveryAgent@7e15f4d4, isProjectLead=true)
Hibernate: select employerde0_.delivery_agent_id as delivery2_2_, employerde0_.employer_id as employer3_2_, employerde0_.is_project_lead as is_proje1_2_ from employer_delivery_agent employerde0_ inner join employer employer1_ on employerde0_.employer_id=employer1_.id where employer1_.id=1
Hibernate: select deliveryag0_.id as id1_0_0_ from delivery_agent deliveryag0_ where deliveryag0_.id=?
Hibernate: select employer0_.id as id1_1_0_ from employer employer0_ where employer0_.id=?
Hibernate: select deliveryag0_.id as id1_0_0_ from delivery_agent deliveryag0_ where deliveryag0_.id=?
EmployerDeliveryAgent(id=com.example.demo.EmployerDeliveryAgentId@3e1, employer=com.example.demo.Employer@62b57479, deliveryAgent=com.example.demo.DeliveryAgent@1903b5d, isProjectLead=false)
EmployerDeliveryAgent(id=com.example.demo.EmployerDeliveryAgentId@400, employer=com.example.demo.Employer@62b57479, deliveryAgent=com.example.demo.DeliveryAgent@5a90265a, isProjectLead=true)
Hibernate: select employerde0_.delivery_agent_id as delivery2_2_, employerde0_.employer_id as employer3_2_, employerde0_.is_project_lead as is_proje1_2_ from employer_delivery_agent employerde0_ inner join employer employer1_ on employerde0_.employer_id=employer1_.id where employer1_.id=1
Hibernate: select deliveryag0_.id as id1_0_0_ from delivery_agent deliveryag0_ where deliveryag0_.id=?
Hibernate: select employer0_.id as id1_1_0_ from employer employer0_ where employer0_.id=?
Hibernate: select deliveryag0_.id as id1_0_0_ from delivery_agent deliveryag0_ where deliveryag0_.id=?
Hibernate: select employerde0_.delivery_agent_id as delivery2_2_0_, employerde0_.employer_id as employer3_2_0_, employerde0_.is_project_lead as is_proje1_2_0_, deliveryag1_.id as id1_0_1_, employer2_.id as id1_1_2_ from employer_delivery_agent employerde0_ inner join delivery_agent deliveryag1_ on employerde0_.delivery_agent_id=deliveryag1_.id inner join employer employer2_ on employerde0_.employer_id=employer2_.id where employerde0_.delivery_agent_id=? and employerde0_.employer_id=?
Hibernate: select employerde0_.delivery_agent_id as delivery2_2_0_, employerde0_.employer_id as employer3_2_0_, employerde0_.is_project_lead as is_proje1_2_0_, deliveryag1_.id as id1_0_1_, employer2_.id as id1_1_2_ from employer_delivery_agent employerde0_ inner join delivery_agent deliveryag1_ on employerde0_.delivery_agent_id=deliveryag1_.id inner join employer employer2_ on employerde0_.employer_id=employer2_.id where employerde0_.delivery_agent_id=? and employerde0_.employer_id=?
Hibernate: delete from employer_delivery_agent where delivery_agent_id=? and employer_id=?
Hibernate: delete from employer_delivery_agent where delivery_agent_id=? and employer_id=?