Question

I'm using JPA with hibernate as provider. There are two entities:

@Entity
@Table(name = "PROYECTOS")
public class Proyecto {
    @Id
    private Long id;
    ...
    @OneToMany(mappedBy = "proyecto", cascade = CascadeType.PERSIST, orphanRemoval = true)
    private List<Incidencia> incidencias;
    ...
}

@Entity
@Table(name = "INCIDENCIAS")
public class Incidencia {
    @Id
    private Long id;
    ...
    @ManyToOne(cascade = CascadeType.PERSIST, optional = false)
    @JoinColumn(name = "ID_PROYECTO", nullable = false)
    @NotNull
    private Proyecto proyecto;
    ...
    public Incidencia(Proyecto proyecto, Usuario usuario, String descripcion,
        Date fechaYHora) {
        super();
        this.proyecto = proyecto;
        this.usuario = usuario;
        this.descripcion = descripcion;
        this.fechaYHora = fechaYHora;
    }
    ...
}

When I execute a test method and try to persist "Incidencia" class ("Proyecto" was persisted before):

...
entityManager.persist(proyecto);
entityManager.flush();
...
Incidencia incidencia = new Incidencia(proyectoFind, usuario,
                "1ª incidencia del proyecto", new Date());
proyecto.getIncidencias().add(incidencia);
entityManager.persist(proyecto);
entityManager.flush();
...

An exception is thrown from the last flush:

    ... 35 more
Caused by: org.h2.jdbc.JdbcBatchUpdateException: La columna "PROYECTO" no permite valores nulos (NULL)
NULL not allowed for column "PROYECTO"; SQL statement:
insert into INCIDENCIAS (DESCRIPCION, FECHA_Y_HORA, ID_PROYECTO, ID_USUARIO, ID) values (?, ?, ?, ?, ?) [23502-175]
    at org.h2.jdbc.JdbcPreparedStatement.executeBatch(JdbcPreparedStatement.java:1167)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
    ... 41 more

I'm sure that "proyecto" is set in "Incidencia" because in its constructor:

this.proyecto = proyecto;

So, I can't understand why this exception is thrown.

Any help is greatly appreciated.

Was it helpful?

Solution

Finally, I've been able to solve the problem. There weren't any problems with the mappings I presented in both classes. Those mappings I showed about Proyecto and Incidencia were different before. The class Incidencia used a compound primary key with an Id class:

@Entity
@Table(name = "INCIDENCIAS")
@IdClass(IncidenciaKey.class)
public class Incidencia implements Serializable { 
    @Id
    @Column(name = "ID")
    private Integer id;
    @Id
    @Column(name = "ID_PROYECTO", nullable = false, insertable = false, updatable = false)
    private Long idProyecto;

    @ManyToOne(cascade = CascadeType.PERSIST)
    @NotNull
    @Valid
    private Proyecto proyecto;
...
}

I only renamed this old version of Incidencia, so there were two classes with @Table(name = "INCIDENCIAS"). I suppose this was the mistake. There was still a column named "PROYECTO" in the in-memory database that it came from this renamed and, as I thought incorrectly, unused entity.

As soon as I moved the renamed Incidencia class out of the package from the database is built everything worked properly.

I want to apoligise for asking this inaccurate question.

Thank you for your help.

OTHER TIPS

After this line

proyecto.getIncidencias().add(incidencia);

you need to set a back reference on the incidencia object

incidencia.setProyecto(proyecto);

then flush.

It does not seem correct that you are passing proyectoFind in the constructor for incidencia and then adding the same object to a different Proyecto object.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top