В настоящее время я сталкиваюсь с некоторыми проблемами при записи объектов в базу данных. Моя проблема возникает с довольно сложной моделью данных, но я постараюсь разбить ее на понятный пример.
Допустим, есть класс 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();
}
...
}
Ссылочный класс B довольно прост: он содержит только @Column
аннотированных атрибутов. Обратите внимание, что экземпляры A могут и будут ссылаться на один и тот же «набор» B s в своем атрибуте b
.
Существует третий класс D , ссылающийся на 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();
}
...
}
Подходя к проблеме:
- Я получаю объекты D из базы данных (ленивый). Ни один из них не ссылается ни на какие объекты A (например, столбец a в базе данных пуст).
- Я извлекаю все объекты A из базы данных с теми же
EntityManager
, как я позже хотел бы вставить их в D экземпляров (также ленивых).
- Я делаю НЕ касаюсь любого атрибута
D#a
или A#b
.
- Попытка
EntityManager#persist
любого вновь созданного экземпляра D приводит к получению следующего исключения:
Caused by: org.hibernate.HibernateException: Found shared references to a collection: random.package.structure.A.b
Во время моего исследования я обнаружил, что ошибка может быть вызвана предоставлением того же Collection
(не путать с Collection
, имеющим те же записи). Очевидно, это связано с инициализацией A экземпляров самой jpa ?! Кажется, будет хорошей идеей перерабатывать тот же Collection
, но, очевидно, вызывает проблемы при обновлении неизмененных объектов ...
Очистка EntityManager
перед сохранением объектов, кажется, решает проблему. Но, поскольку все читается лениво, использование этих объектов впоследствии вызовет другие проблемы.
Есть ли у вас какие-либо советы о том, как создавать новые Collection
s для каждого экземпляра A или предотвращать сбой другими способами?
Заранее большое спасибо, если я пропустил какую-либо информацию, просто спросите!