【问题标题】:org.hibernate.exception.ConstraintViolationException: could not insertorg.hibernate.exception.ConstraintViolationException:无法插入
【发布时间】:2016-07-15 13:52:35
【问题描述】:

当我尝试添加到TDEPOFAZLA 表时,我收到以下错误:

org.springframework.dao.DataIntegrityViolationException:无法插入:[tr.gov.tcmb.pgmtems.model.DepoFazla]; SQL [插入 PGMTEMS.TDEPOFAZLA (ID, FAZLABULUNDURMAORANI, GRUP) 值 (默认, ?, ?)];约束 [null];嵌套异常是 org.hibernate.exception.ConstraintViolationException:无法插入:[tr.gov.tcmb.pgmtems.model.DepoFazla]

这是我的 JUnit 测试函数:

    @Test
public void testSaveDepoFazla() {
    DepoTur depoTur = new DepoTur("my tür", 5);
    depoTurService.saveDepoTur(depoTur);

    List<DepoTur> list = depoTurService.getDepoTurList();
    assertNotNull(list.get(0));

    BigDecimal fazlaBulundurmaOrani = new BigDecimal(6000);
    DepoFazla depoFazla = new DepoFazla(1, list.get(0), fazlaBulundurmaOrani);

    depoFazlaService.saveDepoFazla(depoFazla);
}

这是我的 DepoFazla.java

@Entity
@Table(schema = "PGMTEMS", name = "TDEPOFAZLA")
public class DepoFazla implements Serializable {
    private static final long serialVersionUID = -2800365387332643658L;

    @Id
    @GeneratedValue
    @Column(name = "ID", nullable = false, updatable = false)
    private Long id;

    @Column(name = "GRUP", nullable = false, columnDefinition = "INTEGER")
    private Integer grup;

    @ManyToOne(fetch = FetchType.LAZY, targetEntity = DepoTur.class)
    @JoinColumn(name = "ID", insertable = false, updatable = false)
    @NotNull
    private DepoTur depoTur;

    @Column(name = "FAZLABULUNDURMAORANI", nullable = false, columnDefinition = "DECIMAL(6, 2)")
    private BigDecimal fazlaBulundurmaOrani;

    public DepoFazla() {
        super();
    }

    public DepoFazla(Integer grup, DepoTur depoTur, BigDecimal fazlaBulundurmaOrani) {
        super();
        this.grup = grup;
        this.depoTur = depoTur;
        this.fazlaBulundurmaOrani = fazlaBulundurmaOrani;
    }
//GETTER AND SETTER METHODS
}

这里是 DepoTur.java

@Entity
@Table(schema = "PGMTEMS", name = "TDEPOTUR")
public class DepoTur implements Serializable {
    private static final long serialVersionUID = 6203672609079710060L;

    @Id
    @GeneratedValue
    @Column(name = "ID", nullable = false, updatable = false)
    @Index(name = "XUTDEPOTURP", columnNames = { "id" })
    private Long id;

    @Column(name = "ACIKLAMA", nullable = false)
    private String aciklama;

    @Column(name = "BLOKESIRASI", nullable = false)
    private Integer blokeSirasi; //

    @Column(name = "DEPOCINSI")
    private String depoCinsi;

    public DepoTur() {
        super();
    }

    public DepoTur(String aciklama, Integer blokeSirasi, String depoCinsi) {
        super();
        this.aciklama = aciklama;
        this.depoCinsi = depoCinsi;
        this.blokeSirasi = blokeSirasi;
    }

public DepoTur(String aciklama, Integer blokeSirasi) {
    super();
    this.aciklama = aciklama;
    this.blokeSirasi = blokeSirasi;
}
//GETTER AND SETTER METHODS

当我调试 JUnit 测试时,我得到这个错误:

错误:DB2 SQL 错误:SQLCODE=-407,SQLSTATE=23502,SQLERRMC=TBSPACEID=2,TABLEID=75,COLNO=2,DRIVER=3.50.152 SQLState:23502 错误代码:-407

当我搜索错误时,我发现我尝试插入 NULL 但我无法弄清楚我在哪里添加了 null 值。

这就是我创建 TDEPOFAZLA 表的方式:

    CREATE TABLE TDEPOFAZLA
(
   ID decimal(20,0) PRIMARY KEY NOT NULL,
   GRUP int NOT NULL,
   DEPOTUR decimal(20,0) NOT NULL,
   FAZLABULUNDURMAORANI decimal(6,2) NOT NULL
);
CREATE UNIQUE INDEX XUTDEPOFAZLAP ON TDEPOFAZLA(ID);

这就是我创建 TDEPOTUR 表的方式:

CREATE TABLE TDEPOTUR
(
   ID decimal(20,0) PRIMARY KEY NOT NULL,
   ACIKLAMA varchar(100) NOT NULL,
   DEPOCINSI char(1),
   BLOKESIRASI int NOT NULL
);
CREATE UNIQUE INDEX XUTDEPOTURP ON TDEPOTUR(ID);

对我应该做什么有什么想法吗?

【问题讨论】:

  • 你是否为所有属性定义了getter/setter?
  • TDEPOFAZLA 有四个不可为空的列,而您的插入语句提供的值较少。表定义中ID 没有默认值,DEPOTUR 完全缺失。你为什么用 MySQL> 标记这个
  • @cralfaro 我已经为所有属性定义了 getter/setter 并相应地更新了问题。

标签: java spring hibernate db2


【解决方案1】:

您使用 FK 的属性定义是错误的,因为我看到您使用可更新、可插入为 false,您真正想要的是不修改 FK 对象,因为它可能是某些其他实体通用的主表。

那你可以用的是这个

@ManyToOne(cascade= {CascadeType.DETACH})
@JoinColumn(name = "DEPOTUR")
@NotNull
private DepoTur depoTur;

使用 DETACH,您将仅将值保存在第一个表 DEPOTUR 列中,并且不会更新 DepoTur 表中的对象

在你的第一个表中添加 FK

CREATE TABLE TDEPOFAZLA
(
  ID decimal(20,0) PRIMARY KEY NOT NULL,
  GRUP int NOT NULL,
  DEPOTUR decimal(20,0) NOT NULL,
  FAZLABULUNDURMAORANI decimal(6,2) NOT NULL
);
CREATE UNIQUE INDEX XUTDEPOFAZLAP ON TDEPOFAZLA(ID);
CONSTRAINT fk_column FOREIGN KEY (DEPOTUR) REFERENCES TDEPOTUR(ID);

【讨论】:

  • @supalexy 你能试试我在回复中添加的内容吗?更改映射并创建 FK,如果仍然失败,也许我需要您发送准备对象并进行提交的代码段
  • 感谢您的回复。我已将我的解决方案添加到问题中。
【解决方案2】:

问题是我没有正确引用连接列。这解决了问题:

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "DEPOTUR", referencedColumnName = "ID", nullable = false, columnDefinition = "DECIMAL(20,0)")
@NotNull
private DepoTur depoTur;

【讨论】:

    【解决方案3】:

    您在 DepoFazla 模型中为连接列 ID 指定了两次相同的名称,您必须更改其名称,例如:

    @Entity
    @Table(schema = "PGMTEMS", name = "TDEPOFAZLA")
    public class DepoFazla implements Serializable {
        private static final long serialVersionUID = -2800365387332643658L;
    
        ...
    
        @ManyToOne(fetch = FetchType.LAZY, targetEntity = DepoTur.class)
        @JoinColumn(name = "ID_depoTur", insertable = false, updatable = false)
        @NotNull
        private DepoTur depoTur;
    
        ...
    
    }
    

    【讨论】:

    • 我尝试在数据库和代码中更改 ID 列名称。但是,我仍然遇到同样的错误。
    • @supaplexy 你能在准备对象的地方添加一段Java代码并持久化它吗?
    猜你喜欢
    • 2016-03-28
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 2012-07-30
    • 2018-10-20
    • 2019-11-28
    相关资源
    最近更新 更多