JPA / hibernate错误违反了外键约束

时间:2015-10-19 15:01:31

标签: java hibernate jpa

我是hibernat的新手,我有两个课程,我试图将数据保存在Derby嵌入式数据库中,但是当我保存课程时,我会这样做。来自销售的外键出现以下错误: 错误:

Caused by: ERROR 23503: INSERT on table 'PRODUTOS' caused a violation of foreign key constraint 'FKIOY8UEWC87473SNMMUOPJKUVB' for key (236).  The statement has been rolled back.
    at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
    at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
    at org.apache.derby.impl.sql.execute.ForeignKeyRIChecker.doCheck(Unknown Source)
    at org.apache.derby.impl.sql.execute.RISetChecker.doFKCheck(Unknown Source)
    at org.apache.derby.impl.sql.execute.InsertResultSet.normalInsertCore(Unknown Source)
    at org.apache.derby.impl.sql.execute.InsertResultSet.open(Unknown Source)
    at org.apache.derby.impl.sql.GenericPreparedStatement.executeStmt(Unknown Source)
    at org.apache.derby.impl.sql.GenericPreparedStatement.execute(Unknown Source)
    ... 82 more

班文达:

@Entity
@Table(name = "Venda")
@Access(value = AccessType.PROPERTY)
public class Venda {

    @Id
    @GeneratedValue
    @Column(name = "venda_id")
    public Long getId() {
        return id;
    }

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "produtos_id")
    public List<Produtos> getProdutos() {
        return produtos;
    }

    public void setProdutos(List<Produtos> produtos) {
        this.produtos = produtos;
    }

    [...]
}

类Produtos:

@Entity
@Table(name = "Produtos")
@Access(value = AccessType.PROPERTY)
public class Produtos {       

    @Id
    @GeneratedValue
    @Column(name = "produtos_id")
    public Long getId() {
        return id;
    }


    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name = "venda_id", nullable = false)
    public Venda getVenda() {
        return venda;
    }

    [...]
}

保存:

EntityManagerFactory factory =   Persistence.createEntityManagerFactory("cliente");
EntityManager manager = factory.createEntityManager();
manager.getTransaction().begin();
manager.persist(venda);
for (Produtos produto : produtos) {
    produto.setVenda(venda);
}
for (Produtos produto : produtos) {

    manager.persist(produto);
}

manager.getTransaction().commit();
manager.close();
factory.close();

3 个答案:

答案 0 :(得分:2)

除了其他答案:

  

...违反外键约束&#39; FKIOY8UEWC87473SNMMUOPJKUVB&#39; ...

  1. 不知道FKIOY8UEWC87473SNMMUOPJKUVB究竟意味着什么, 要识别真正的问题(仅通过阅读您的代码)并不容易 有可能的是,数据库中存在一个约束,该约束在代码中被删除(稍后) 您应首先检查如何定义名为FKIOY8UEWC87473SNMMUOPJKUVB的约束。
  2. 您可以在Hibernate映射文件hbm.xml中定义自己的FK名称:

    <many-to-one class="sample.SampleEntity" fetch="select" foreign-key="FK_sampleNameForFK" name="sample">
        <column name="sample_id"/>
    </many-to-one>
    

答案 1 :(得分:1)

@JoinColumn只应在关系的一侧指定。它通常放在拥有实体的一边。在“多对一”和“一对多”双向关系中,这通常放在使用@ManyToOne映射的字段上。

因此,我建议您删除@JoinColumn方法上的getProdutos()映射。只需在许多方面留下一个@JoinColumn

此外,由于这是双向关系,因此您应在mappedBy注释上指定@OneToMany属性,以指示这是关系的反面。

在应用我的建议之后,这是一个示例结果代码:

@Entity
public class Venda {
...

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy="venda")    
    public List<Produtos> getProdutos() {
        return produtos;
    }
...
}

@Entity
public class Produtos {       
...
    @ManyToOne
    @JoinColumn(name = "venda_id", nullable = false)
    public Venda getVenda() {
        return venda;
    }
...
}

答案 2 :(得分:0)

您已在Venda实体类中放置了cascade = CascadeType.ALL。这意味着Produto列表保存在Venda设置中。因此,第二次尝试保存Produto时会出现约束违规异常,因为它已经被保存。