So I have a many-to-many relationship that goes like this:
@Entity
@Table(name="A")
public class A {
@Id
@SequenceGenerator(...)
@GeneratedValue(strategy = SEQUENCE, ...)
private Long id;
@ManyToMany(
cascade = CascadeType.PERSIST,
fetch = FetchType.EAGER
)
@JoinTable(...)
private Set<B> b;
}
I have cascade = CascadeType.PERSIST in the many-to-many relationship so that when I save A, B is persisted along with it.
But, as you can see B has a @UniqueConstraint:
@Entity
@Table(
name="B",
uniqueConstraints = @UniqueConstraint(name = "b_name_unique", columnNames = "name")
)
public class B {
@Id
@SequenceGenerator(name = "b_sequence", sequenceName = "b_sequence", allocationSize = 1)
@GeneratedValue(strategy = SEQUENCE, generator = "b_sequence")
private Long id;
@Column(name = "name", nullable = false)
private String name;
@ManyToMany(mappedBy = "b")
private Set<A> a;
}
The problem is, of course, when try to save two different A entities with B entities with the same name, or even with the exact same B entity, it throws the following error:
Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "b_name_unique"
Detail: Key (name)=(myname) already exists.
Which makes sense, since it's doing the following:
Hibernate: insert into B (name, id) values (?, ?)
o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [myname] <--------------------\
o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [BIGINT] - [1] |
|
Hibernate: insert into B (name, id) values (?, ?) |
|
o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [myname] <--------------------|
o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [BIGINT] - [2] <--------- +1 even though name is the same
o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 23505 |
o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: duplicate key value violates unique constraint "b_name_unique" <---------/
What I want to do is find a way to save multiple A entities that have B entities in common. For example:
save A(id=null, b=B(id=null, name=myname)) -> find A(id=1, b=B(id=1, name=myname))
save A(id=null, b=B(id=null, name=myname)) -> find A(id=2, b=B(id=1, name=myname))
The only workaround I've found so far is to:
- make a set of all the common B entities in A entities and
- save those first, and then
- save the A entities.
And that works somehow.