Spring JPA - @ OneToOne / @ MapsId - Родитель / ребенок с общим ключом: я получаю это исключение GenerationException: попытка назначить идентификатор из нулевого однозначного свойства - PullRequest
0 голосов
/ 26 мая 2020

При добавлении родителя и потомка с отношением @ OneToOne с одним и тем же ключом я продолжаю получать эту ошибку. Рекомендуется использовать @MapsId.

id.IdentifierGenerationException: попытка назначить id из нуля однозначное свойство

Обычные решения I пробовал, но это не решило проблему.

  • Наличие как родительской, так и дочерней точки указывает друг на друга
  • Правильная транзакционная (являющаяся Springframework)
  • Сохранение с использованием репо владельца. Это не работает из-за нарушения верхнего ограничения.

Моя родительская сущность (с именами, имеющими цель):

@Entity
@Table(name = "JOHAN_SHARED_SUPPLIER")
public class EntitySharedSupplier {
    @Id
    @Column(name = "supplier_shared_id")
    private Long javaSharedSupplierId;

    @Column(name = "supplier_shared_name")
    private String javaSharedSupplierName;

    @Column(name = "contact_shared_name")
    private String javaSharedSupplierContactName;

    @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY,
            mappedBy = "supplierSharedRef", orphanRemoval = true)
    private EntitySharedProduct javaSharedProduct;

Дочерний:

@Entity
@Table(name = "JOHAN_SHARED_PRODUCTS")
public class EntitySharedProduct {
    @Id
    @Column(name = "shared_supplier_id")
    private Long javaSupplierSharedId;

    @MapsId
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="shared_supplier_id")
    private EntitySharedSupplier supplierSharedRef;

    @Column(name = "prod_supplier_name")
    private String javaSharedProductName;

Репо родительского объекта:

@Repository
@Transactional
public interface SupplierSharedRepo extends JpaRepository<EntitySharedSupplier, Long> {
}

Код услуги:

@Transactional
public void saveSupplier(int sup) {
    EntitySharedSupplier supplier = new EntitySharedSupplier();
    supplier.setJavaSharedSupplierId((long) sup);
    supplier.setJavaSharedSupplierName("SharedSupplier-" + sup);
    supplier.setJavaSharedSupplierContactName("SharedSupplier-contact-" + sup);
    EntitySharedProduct product = new EntitySharedProduct();
    product.setJavaSharedProductName("SharedSupplier-Book-" + sup);
    product.setSupplierSharedRef(supplier);
    supplier.setJavaSharedProduct( product);
    supplierSharedRepo.save(supplier);
}

1 Ответ

0 голосов
/ 27 мая 2020

Решение в этом случае было немного сложным.

Решение заключается в изменении метода set id / key в родительском объекте:

public void setJavaSharedSupplierId(Long javaSupplierId) {
    this.javaSharedSupplierId = javaSupplierId;
    if( javaSharedProduct != null) {
        javaSharedProduct.setJavaSupplierSharedId( javaSupplierId);
    }
}

УВЕДОМЛЕНИЕ :

  • В большинстве случаев в случаях, когда у вас есть automati c id / key генерация родительского на поздней стадии во время процесса сохранения hibernate / jpa. В этот момент связь между родителем и ребенком уже установлена.
  • В этом случае решение работает, потому что сначала устанавливается соединение между родительским и дочерним, а затем устанавливается ручной идентификатор / ключ родительского .

До тех пор я продолжал получать либо исходную ошибку (как показано в вопросе), либо то, что идентификатор идентификатора не был установлен.

Решение требует небольшого изменения в создании родительских / дочерних объектов.

@Transactional
public void saveSupplier(int sup) {
    EntitySharedSupplier supplier = new EntitySharedSupplier();
    supplier.setJavaSharedSupplierName("SharedSupplier-" + sup);
    supplier.setJavaSharedSupplierContactName("SharedSupplier-contact-" + sup);
    EntitySharedProduct product = new EntitySharedProduct();
    product.setJavaSharedProductName("SharedSupplier-Book-" + sup);
    product.setSupplierSharedRef(supplier);
    supplier.setJavaSharedProduct( product);
    // The next statement has to be put after the previous
    supplier.setJavaSharedSupplierId((long) sup);
    supplierSharedRepo.save(supplier);
}

Решение работает и его легко понять. У меня также есть программное обеспечение, которое не требует ручной настройки дочернего идентификатора в родительском идентификаторе. Пока я не понял, почему это программное обеспечение работает.

Если у вас есть лучшее решение, дайте мне / нам знать!

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