Hibernate выбрасывает «NULL не разрешено для столбца», так как FK отношения JPA OneToOne отсутствует в SQL INSERT при использовании @MapsId - PullRequest
1 голос
/ 25 июня 2019

В отношении OneToOne я получаю: NULL not allowed for column "USER_ID"; SQL statement: insert into customer_order (id, enabled, orden_id) values (null, ?, ?).

На самом деле это null, потому что его нет в запросе INSERT. Однако значение USER заполняется в сущности customerOder при выполнении save(customerOrder).

@Getter
@SuperBuilder
@MappedSuperclass
@NoArgsConstructor
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public abstract class AbstractEntity {

    @Id
    @EqualsAndHashCode.Include
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Setter
    @Default
    @Column(columnDefinition = "BOOLEAN DEFAULT 'true'", nullable = false)
    private Boolean enabled = Boolean.TRUE;
}

@Getter
@Setter
@Entity
@Table(name = "customer_order")
@SuperBuilder
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true)
public class CustomerOrderEntity extends AbstractEntity {

    @OneToOne(fetch = FetchType.LAZY)
    @MapsId("id")
    private UserEntity user;

       //other values
}

@Data
@Entity
@Table(name = "user")
@SuperBuilder
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true)
public class UserEntity extends AbstractEntity {

    @NaturalId
    @EqualsAndHashCode.Include
    @Column(length = 28, unique = true, nullable = false)
    private String uuid;

//other values
}

Я ожидаю, что customerOrder сохранится в базе данных с заполненными данными.

Ответы [ 2 ]

1 голос
/ 26 июня 2019

Как я объяснил в этой статье , использование @MapsId позволяет использовать первичный ключ дочерней таблицы в качестве внешнего ключа для первичного ключа родительской таблицы.

Если вы включите инструмент hbm2ddl, вы увидите, что таблица customer_order не будет содержать столбец user_id.

Однако, поскольку вы сгенерировали схему базы данных ранее и у вас есть таблица customer_order с выделенным столбцом user_id, вам необходимо удалить @MapsId:

@OneToOne(fetch = FetchType.LAZY)
private UserEntity user;

Таким образом, ассоциация user будет использовать столбец user_id Foreign Key.

Для получения более подробной информации о наилучшем способе сопоставления индивидуальной связи с JPA и Hibernate, ознакомьтесь с этой статьей .

0 голосов
/ 26 июня 2019

Ваш код работает точно так, как вы указали.

Если у вас есть общий ключ (вы используете @MapsId), Hibernate не будет использовать отдельный столбец для внешнего ключа. Вот почему запрос на вставку не содержит столбец user_id.

Сверху, если это так, идентификатор в CustomerOrderEntity, с одной стороны, генерируется автоматически (как определено в суперклассе), а на другой карте - идентификатор другой сущности. Это противоречивые требования.

...