I'm a bit confused about the way Hibernate handles inserts into the JoinTable.
I need some extra fields in the JoinTable, so I chose the pretty common way, to create an @Entity for the JoinTable and use @OneToMany and @ManyToOne. And because the relations should be unique I created an @EmbeddedId within the JoinTable-Entity.
Lets call the classes A, B and AB:
@Entity
public class A implements Serializable {
    @OneToMany(mappedBy="a", cascade=CascadeType.ALL, orphanRemoval=true)
    private Set<AB> abs;        
}
@Entity
public class B implements Serializable {
    @OneToMany(mappedBy="b", cascade=CascadeType.ALL, orphanRemoval=true)
    private Set<AB> abs;        
}
@Entity
public class AB implements Serializable {
    @Embeddable
    public static class Id implements Serializable {
        UUID aId;
        UUID bId;
        public Id(UUID aId, UUID bId) {
            this.aId = aId;
            this.bId = bId;
        }
    }
    public AB(A a, B b) {
        this.id.aId = a.getId();
        this.id.bId = b.getId();
        this.a = a;
        this.b = b;
    }
    @EmbeddedId
    private Id id;      
    @MapsId("aId")
    @ManyToOne
    @JoinColumn(nullable=false, updatable=false)
    private A a;
    @MapsId("bId")
    @ManyToOne
    @JoinColumn(nullable=false, updatable=false)
    private B b;        
}
My commons case is, that I want to insert multiple new entries in to the JoinTable. So I have ONE A_id and multiple B_ids. In plain SQL, I'd simply do ONE query to get it all done. If the relation did already exist, the database will throw an error.
With hibernate I need to:
- SELECT: give me an instance of class- Afor id =- A_id
- SELECT: give me an instance of class- Bfor id =- B_id1or id =- B_id2or ...
- Create a new instance of class ABand set the composite primary key and saveAB
The last step produces (for each AB):
- select * from AB where a_id = ... and b_id = ...
- insert into AB (aId, bId) values (..., ...)
Here's my code. Using spring data jpa (JpaRepository):
A a = aRepo.findOne(aId);
List<B> bs = bRepo.findAll(bIdList);
for(B b : bs) {
    AB ab = new AB(a, b);
    abRepo.save(ab);
}
groupUserRepo.flush();
It doesn't matter if I just create a new ArrayList with the AB objects and afterwards save all of them at once or if I do it like in the code above. It always does a select and an insert for each object.
Is there a way to do it with less queries?
 
    