【问题标题】:JPA OneToMany and ManyToOne: Error NULL not allowed for columnJPA OneToMany 和 ManyToOne:列不允许出现错误 NULL
【发布时间】:2014-03-27 20:22:22
【问题描述】:

我正在使用 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;
    }
    ...
}

当我执行测试方法并尝试持久化“Incidencia”类时(“Proyecto”之前已持久化):

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

我确定“proyecto”设置在“Incidencia”中,因为在它的构造函数中:

this.proyecto = proyecto;

所以,我不明白为什么会抛出这个异常。

非常感谢任何帮助。

【问题讨论】:

  • 你检查过proyectoFind有一个非空值吗?
  • 必须为您的变量和类使用正确的英文单词。阅读您的代码很痛苦!!!
  • 对不起,我在这个问题中没有使用英文单词来表示变量和类。这是我的第一个问题,我还没有处理这个问题。在接下来的问题中,我会尽量使用英语单词。我检查了“proyecto”(我错误地称之为“proyectoFind”)没有空值。非常感谢。
  • 你能列出数据库表INCIDENCIAS中的所有列吗?该错误表明名为 PROYECTO 的列存在问题,而不是 ID_PROYECTO。
  • 异常说: 引起:org.h2.jdbc.JdbcBatchUpdateException: La columna "PROYECTO" no permite valores nulos (NULL) NULL not allowed for column "PROYECTO"; SQL语句:插入INCIDENCIAS(USUARIO_CREACION,FECHA_CREACION,DESCRIPCION,FECHA_Y_HORA,USUARIO_ULTIMA_MODIFICACION,FECHA_ULTIMA_MODIFICACION,ID_PROYECTO,ID_USUARIO,VERSION,ID)值(?,?,?,?,?,?,?,?,?,?)[ 23502-175]。句子中出现的列与我在课堂上定义的相同。 PROYECTO 列未在类中定义。供您参考,我正在使用内存数据库 H2。

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


【解决方案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 类从数据库中移出包,一切都会正常运行。

我想为这个不准确的问题道歉。

感谢您的帮助。

【讨论】:

    【解决方案2】:

    这一行之后

    proyecto.getIncidencias().add(incidencia);
    

    您需要在事件对象上设置反向引用

    incidencia.setProyecto(proyecto);
    

    然后冲洗。

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

    【讨论】:

    • 感谢您的回答。很抱歉,“proyectoFind”是我编写的代码中的一个错误。我还尝试使用默认构造函数并设置“Incidencia”的变量,而不是使用带参数的构造函数。我还检查了“proyecto”没有空值。而且我还按照您的建议在事件对象上设置了反向引用。但是抛出了同样的异常。
    • 所以,我使用:Incidencia incidencia = new Incidencia(proyecto, usuario, "1ª incidencia del proyecto", new Date());而不是:Incidencia incidencia = new Incidencia(proyectoFind, usuario, "1ª incidencia del proyecto", new Date());但是抛出了同样的异常。
    • proyecto的主键设置了吗?
    • 是的。在持久化 proyecto 对象并刷新之后,我检查了 proyecto 的所有属性。所有这些都是正确的,并且它的主键(id)也是正确的。然后,我用这个 proyecto 创建 incidencia 对象,将 incidencia 添加到 proyecto,在 incidencia 对象上设置一个反向引用(我认为这是多余的),最后,刷新。但是仍然抛出异常。
    猜你喜欢
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    相关资源
    最近更新 更多