JPA is not saving because it keep telling that a foreign key is null when it's not

Viewed 86

A really weird problem happen to me, I just solved it after a day. I'm just writing here to try to find out some explanation.

This is my original piece of code, inside a method that fetch some data to be insert or updated in the DB through JPA (.save(soggetto)):

DSoggettoA soggettoA = soggetto.getSoggettoA();
if (soggettoA==null) {
    soggettoA = new DSoggettoA();
    soggetto.setSoggettoA(soggettoA);   //<----- THIS LINE!!!!!!!
    soggettoA.setSoggetto(soggetto);
    soggettoA.setFkDSoggetto(soggetto.getIdDSoggetto());
}
DettaglioSoggettoMapper.INSTANCE.dettaglioSoggettoAToDSoggettoA(soggettoA,
        domande.getDettaglioSoggettoA());
setProvinciaAndComune(soggettoA, domande.getDettaglioSoggettoA()); //Set provincia retrieved through a findBy query

With this code, JPA throws me an Oracle exception, as if the value of provincia is null:

ORA-01400: cannot insert null in ("D_SOGGETTO_A"."FK_T_PROVINCIA")

But if I move the line commented with "THIS LINE!!!" to the really bottom of the code (after the line with setProvinciaAndComune), all works fine.

Why does this happen? In theory if I set the reference of soggettoA inside soggetto it should not matter where or when this happen I only need to do that before persisting the entity, is it right?

Edit 19/09: the error happens only when the rows on DSoggettoA is not existing, but if I move soggetto.setSoggettoA(soggettoA); to the bottom the problem is not popping up:

@Entity
@Table(name="d_soggetto")
@Getter
@Setter
public class DSoggetto implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="id_d_soggetto")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer idDSoggetto;

    @OneToOne(mappedBy="soggetto", cascade=CascadeType.ALL, orphanRemoval = true)
    private DSoggettoA soggettoA;
}


@Entity
@Table(name="D_SOGGETTO_A")
@Getter
@Setter
public class DSoggettoA implements Serializable, ProvinciaComune {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="FK_D_SOGGETTO")
    private Integer fkDSoggetto;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "fk_t_provincia")
    private TProvincia provincia;
}


@Entity
@Table(name="t_provincia")
@Getter
@Setter
public class TProvincia implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="id_t_provincia")
    private Integer idTProvincia;

    @OneToMany(mappedBy = "provincia")
    private List<DSoggettoA> soggettoA;
}


//Service method:
@Override
@Transactional
public void foo(final Bar bar) {
    // call a method that return existing DSoggetto and populate it with 
    // DSoggettoA as in the first method that I posted...
    soggettoRepository.save(retrieveExistingDSoggetto(bar));
}
0 Answers
Related