JPA: отображение пересекло отношения OneToOne и ManyToOne - PullRequest
0 голосов
/ 12 апреля 2020

У меня есть две сущности, которые мы назовем A и B. B всегда имеет A в качестве родителя с отношением ManyToOne. Однако мне нужно, чтобы A имел отношение OneToOne с последней записью, вставленной в таблицу B. Это потому, что мне нужно сохранить несколько версий B, но в 99% случаев нужно будет использовать только самую последнюю.

Это выглядит примерно так:

@Data
@Entity
public class A {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Setter(AccessLevel.NONE)
    private Long id;

    /* Properties
       ...
    */

    @OneToOne(optional = false)
    private B latest;
}
@Data
@Entity
public class B {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Setter(AccessLevel.NONE)
    private Long id;

    /* Properties
       ...
    */

    @Column(nullable = false)
    private Date lastModified;

    @ManyToOne(optional = false)
    private A parent;
}

Теперь проблема заключается в том, что я не могу сохранять эти сущности, так как каждый из них кажется временным:

  • A не может быть сохранен, потому что latest ссылается на B, но B не сохраняется.
  • B не может быть сохранен, поскольку parent ссылается на A, но A не сохраняется.

Попытка сделать это приводит к:

java .lang.IllegalStateException: org.hibernate.TransientPropertyValueException: свойство Not-null ссылается на временное значение - временный экземпляр должен быть сохранен перед текущей операцией: B .parent -> A

Я попытался обернуть код, отвечающий за их сохранение, в методе @Transactional, но происходит то же самое:

@Transactional
public void saveAB(A parent, B child) {
    parent.setLatest(child);
    child.setParent(parent);
    Arepository.save(parent);
    Brepository.save(child);
}

Я также подумал о d рассматривает отношение OneToOne от A к B, вместо этого имея latest в качестве переходного поля @Formula, которое будет запрашивать B для получения самой последней записи. Однако @Formula, по-видимому, ограничивается примитивами, а не полными сущностями.

Каков будет правильный способ сделать это с JPA? Я неправильно подхожу к этому?

1 Ответ

0 голосов
/ 13 апреля 2020

Поскольку A и B зависят друг от друга, их, вероятно, следует рассматривать как один агрегат с A как агрегат root.

Это означает, что вы ' у меня есть только ARepository, а также CascadeType.ALL в отношениях.

...