Reputation: 45
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();
Upvotes: 2
Views: 7689
Reputation: 3518
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>
Upvotes: 2
Reputation: 4154
@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;
}
...
}
Upvotes: 1
Reputation: 1584
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.
Upvotes: -1