I'm currently facing some trouble writing objects to database. My problem does arise with a quite complex data model, but I will try break it down to an understandable example.
Let's say there is class A:
@Entity(name = "a")
@Table(schema = "foo")
public class A {
private static final long serialVersionUID = -5305374150112492804L;
logger = LoggerFactory.getLogger(A.class);
@Id
@Column(name = "tid", nullable = false, unique = true)
@SequenceGenerator(name = "globalSequenceGen", schema = "foo", sequenceName = "foo_sequence")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "globalSequenceGen")
private Integer TID;
@Column(name = "b")
private String bId;
@OneToMany(targetEntity = B.class)
@JoinColumn(name = "random_b_attribute", referencedColumnName = "b", updatable = false, insertable = false)
private List<B> b;
@PrePersist
@PreUpdate
public void prePersist() {
bId = b == null || b.isEmpty() ? null : b.get(0).getRandomAttribute();
}
...
}
The referenced class B is quite simple: It only contains @Column
annotated attributes. Please notice, that instances of A can and will refer to the same "Set" of Bs in it's attribute b
.
There is a third class D referencing A:
@Entity(name = "d")
@Table(schema = "foo")
public class D {
private static final long serialVersionUID = -5305374150112492804L;
logger = LoggerFactory.getLogger(D.class);
@Id
@Column(name = "tid", nullable = false, unique = true)
@SequenceGenerator(name = "globalSequenceGen", schema = "foo", sequenceName = "foo_sequence")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "globalSequenceGen")
private Integer TID;
@Column(name = "a")
private Integer aId;
@ManyToOne(targetEntity = A.class)
@JoinColumn(name = "a", referencedColumnName = "tid", updatable = false, insertable = false)
private A a;
@PrePersist
@PreUpdate
public void prePersist() {
aId = a == null ? null : a.getTID();
}
...
}
Coming to the problem:
EntityManager
as I would later like to insert them into D instances (also lazy).D#a
nor A#b
attribute.EntityManager#persist
any newly created instance of D ends up in getting the following exception:Caused by: org.hibernate.HibernateException: Found shared references to a collection: random.package.structure.A.b
During my research I found, that the error may be caused when providing the same Collection
(not to be confused with a Collection
having the same entries). Obviously this stems from initialisation of A instances by jpa itself?! Seems, to be a good idea to recycle the same Collection
, but obviously causes problems when updating the unaltered objects...
Clearing the EntityManager
before persisting objects seem to solve the problem. But, as everything is read lazy using those objects afterwards will cause other problems.
Do you have any hint on how to create new Collection
s for every instance of A or prevent the failure in other ways?
Many thanks in advance, if I did miss any information, please just ask!
Thanks a lot for your answers! The hint of @crizzis did the trick.
Of course it is a @ManyToMany
relation. I altered my data model (to use Mapping tables) and that solved my problem!