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'...
FKIOY8UEWC87473SNMMUOPJKUVB
exactly means, it's not easy to identify the real problem (only by reading your code). FKIOY8UEWC87473SNMMUOPJKUVB
is defined. 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.