简体   繁体   中英

JPA/hibernate error violation of foreign key constraint

I'm new to hibernat and i have two class and I'm trying to save the data in a Derby embedded database , however when I save the class 'produto ' with foreign key from the sale appears the following error: Error:

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

class Venda:

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

    [...]
}

class 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;
    }

    [...]
}

Saving:

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

Beside the other answers:

...violation of foreign key constraint 'FKIOY8UEWC87473SNMMUOPJKUVB'...

  1. Without knowing what FKIOY8UEWC87473SNMMUOPJKUVB exactly means, it's not easy to identify the real problem (only by reading your code).
    It may be possible, that there exists an constraint in the database, which was removed (later) in code.
    You should check first, how the constraint named FKIOY8UEWC87473SNMMUOPJKUVB is defined.
  2. You can define your own FK-Names in the Hibernate mapping file hbm.xml :

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

@JoinColumn should only be specified on one side of the relationship. It is usually placed on the side of the owning entity. In the Many-To-One and One-To-Many bi-directional relationship, this is usually placed on the field mapped with @ManyToOne .

So, I suggest to remove the @JoinColumn mapping on your getProdutos() method. Just leave one @JoinColumn on the many side.

Also, since this is a bi-directional relationship, you should specify a mappedBy attribute on the @OneToMany annotation to indicate that this is the inverse side of the relationship.

Here's a sample resulting code, after applying my suggestions:

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

You've put cascade = CascadeType.ALL in Venda entity class. This means that Produto list is saved on Venda setting. As a result the second time you try to save Produto gives you constraint violation exception cause it has been already saved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM