JPA OneToMany和ManyToOne:列不允许使用NULL NULL

时间:2014-03-27 20:22:23

标签: java hibernate jpa one-to-many many-to-one

我使用JPA和hibernate作为提供者。有两个实体:

@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;
    }
    ...
}

当我执行测试方法并尝试坚持&#34; Incidencia&#34; class(&#34; Proyecto&#34;之前一直存在):

...
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();
...

从最后一次刷新中抛出异常:

    ... 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

我确信&#34; proyecto&#34;设置在&#34; Incidencia&#34;因为在它的构造函数中:

this.proyecto = proyecto;

所以,我无法理解为什么抛出这个异常。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

最后,我已经能够解决问题了。 我在两个班级中提出的映射都没有任何问题。我展示的关于Proyecto和Incidencia的那些映射在之前是不同的。 Incidencia类使用复合主键和Id类:

@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;
...
}

我只重命名了这个旧版本的Incidencia,所以有两个类@Table(name =“INCIDENCIAS”)。我想这是错误的。在内存数据库中仍然有一个名为“PROYECTO”的列,它来自重命名的,并且我认为不正确,是未使用的实体。

一旦我从数据库中移出重命名的Incidencia类从包中取出,一切正常。

我想要问这个不准确的问题。

感谢您的帮助。

答案 1 :(得分:0)

此行之后

proyecto.getIncidencias().add(incidencia);

您需要在incidencia对象上设置后向引用

incidencia.setProyecto(proyecto);

然后冲洗。

在incidencia的构造函数中传递proyectoFind然后将相同的对象添加到不同的Proyecto对象似乎是不正确的。