Как создать связь между новой сущностью и существующей без обновления существующей сущности? - PullRequest
0 голосов
/ 21 октября 2019

У меня есть объект Phone и объект PhoneType. Каждый телефон имеет 1 PhoneType, и у каждого PhoneType может быть много телефонов.

Я хочу добавить новый телефон при использовании существующего PhoneType, но когда я создаю новый телефон, как мне создать связь с существующимPhoneType без извлечения PhoneType из БД и без обновления существующего PhoneType?

Я попытался просто создать новый PhoneType с существующим идентификатором, который затем попытается обновить запись PhoneType. Я не хочу, чтобы это обновление происходило.

Я также пытался изменить CascadeType в поле PhoneType в Phone, но у меня возникли проблемы с пониманием того, что делают эти различные типы.

В объекте Phone:

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "phone_type_id", referencedColumnName = "id")
    private PhoneType phoneType;

И сущность PhoneType:

@Getter
@Setter
@EqualsAndHashCode
@Entity
@Table(name = "phone_type")
public class PhoneType {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "description", length = 175, nullable = false)
    private String description;

    @Column(name = "name", length = 175, nullable = false)
    private String name;
}

и, наконец, создание сущностей / отношений:

    return new Phone()
            .setNumber(phoneNumber)
            .setPhoneType(new PhoneType().setId(defaultPhoneTypeId))
  }

В этом случае происходит именно то, что вы ожидаете, спящий режим пытается обновитьPhoneType с кучей пустых полей, где id PhoneType = defaultPhoneTypeId.

Используя CascadeType.MERGE, я получаю следующую ошибку:

java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.phoneType -> com.PhoneType

Пока это ожидается, я понятия не имею,как создать связь с 1 новым и 1 уже существующим объектом.

1 Ответ

0 голосов
/ 22 октября 2019

Вы указали тип каскада как CascadeType.ALL Это каскадирует все операции для сопоставленной сущности. Таким образом, при сохранении телефона вы каскадно выполняете операцию сохранения и просите ORM также сохранить тип телефона.

Попробуйте полностью удалить его. Тип каскада по умолчанию Каскад не используется.

    @ManyToOne
    @JoinColumn(name = "phone_type_id", referencedColumnName = "id")
    private PhoneType phoneType;

При создании объекта телефона вы можете получить phoneType по идентификатору из БД, а затем установить его в объекте телефона перед сохранением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...