1

I am facing an issue with JPA @OneToOne bidirectional relationship. It doesn't link child entity to the parent, keeps parent's ID null. I use Spring Boot 2.6.3 (latest) and JpaRepository. Here are some snippets:

Entity A

@Entity
@Table(name = "A")
public class A {
    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idSeq")
    @SequenceGenerator(name="idSeq",
            sequenceName="A_ID_SEQ",
            allocationSize = 1)
    private Long id;

    @NotNull
    @JoinColumn(name = "B_ID")
    @OneToOne(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
    private B b;

// getters, setters, equals, hashcode
}

Entity B

@Entity
@Table(name = "B")
public class B {
    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idSeq")
    @SequenceGenerator(name="idSeq",
            sequenceName="B_ID_SEQ",
            allocationSize = 1)
    private Long id;

    @NotNull
    @OneToOne(mappedBy = "b", cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
    private A a;

// getters, setters, equals, hashcode
}

Service:

@Transactional
public List<Long> submit(List<Dto> dtos) {
    return dtos.stream()
        .map(dto -> {
            A a = Converter.toA(dto);
            a.getB().setA(A);
            a = ARepository.save(a);
            return a.getId();
        })
        .collect(Collectors.toList());
}

repositories:

@Repository
public interface ARepository extends CrudRepository<A, Long> {
}

@Repository
public interface BRepository extends CrudRepository<B, Long> {
    B findByAId(Long id);
}

What I see in log:

2022-01-27 19:38:34,571 DEBUG SQL - [][] select a_id_seq.nextval from dual
2022-01-27 19:38:34,791 DEBUG SequenceStructure - [][] Sequence value obtained: 93027396
2022-01-27 19:38:34,793 DEBUG ResourceRegistryStandardImpl - [][] HHH000387: ResultSet's statement was not registered
2022-01-27 19:38:34,801 DEBUG AbstractSaveEventListener - [][] Generated identifier: 93027396, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator
2022-01-27 19:38:34,840 DEBUG SQL - [][] select b_id_seq.nextval from dual
2022-01-27 19:38:34,976 DEBUG SequenceStructure - [][] Sequence value obtained: 537
2022-01-27 19:38:34,977 DEBUG ResourceRegistryStandardImpl - [][] HHH000387: ResultSet's statement was not registered
2022-01-27 19:38:34,980 DEBUG AbstractSaveEventListener - [][] Generated identifier: 537, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator

As you can see, Hibernate resolves everything it needs to save both entities:

...
EntityPrinter - [][] com.test.model.entity.A{id=93027396, b=com.test.model.entity.B#537}
EntityPrinter - [][] com.test.model.entity.B{a=com.test.model.entity.A#93027396, id=537}
...

but

...
SQL - [][] insert into B (id) values (?)
...
TRACE BasicBinder - [][] binding parameter [1] as [BIGINT] - [537]

As a result, B.A_ID is null. What I missed?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Green Root
  • 644
  • 2
  • 10
  • 28

0 Answers0