1

私は3日間、この問題に悩まされています。できるだけ明確に説明しようとしています。ソフトウェアの在庫管理に取り組んでおり、データベースの管理にはEclipseLink(JPA2.0)を使用しています。問題は、関連する記事を含む新しい請求書を作成し、それらを永続化しようとすると、 Referential integrity constraint violation Exception...

本当の問題は、netbeansを使用してすべてのエンティティを生成し(アノテーションに精通していないため)、それらが正しく生成されているかどうかを確認できないことです(ただし、それでも疑問です)。

テーブルSQL:

ここに画像の説明を入力してください

CREATE TABLE fact_proforma (
  idfact_proforma INT UNSIGNED NOT NULL AUTO_INCREMENT,
  utilisateur_login VARCHAR(25) NOT NULL,
  client_idclient INT UNSIGNED NOT NULL,
  date DATE NOT NULL,
  PRIMARY KEY(idfact_proforma),
  FOREIGN KEY(client_idclient)
    REFERENCES client(idclient)
      ON DELETE NO ACTION
      ON UPDATE CASCADE,
  FOREIGN KEY(utilisateur_login)
    REFERENCES utilisateur(login)
      ON DELETE NO ACTION
      ON UPDATE CASCADE
);



CREATE TABLE fact_proforma_has_article (
  fact_proforma_idfact_proforma INT UNSIGNED NOT NULL,
  article_idarticle VARCHAR(40) NOT NULL,
  prix_ht DOUBLE NOT NULL,
  qte DOUBLE  NOT NULL,
  remise DOUBLE NOT NULL,
  marge_benef DOUBLE NOT NULL,
  PRIMARY KEY(fact_proforma_idfact_proforma, article_idarticle),
  FOREIGN KEY(fact_proforma_idfact_proforma)
    REFERENCES fact_proforma(idfact_proforma)
      ON DELETE CASCADE
      ON UPDATE CASCADE,
  FOREIGN KEY(article_idarticle)
    REFERENCES article(idarticle)
      ON DELETE NO ACTION
      ON UPDATE CASCADE
);


CREATE TABLE article (
  idarticle VARCHAR(40) NOT NULL,
  libel VARCHAR(100) NOT NULL,
  prix_ht DOUBLE NOT NULL,
  tva_idtva DOUBLE NOT NULL,
  qte DOUBLE NOT NULL,
  min_qte DOUBLE  NOT NULL,
  marge_benef DOUBLE NOT NULL,
  remise DOUBLE NOT NULL,
  unite_idunite VARCHAR(10) NOT NULL,
  famille_idfamille VARCHAR(50) NOT NULL,
  etat CHAR(1) NOT NULL,
  PRIMARY KEY(idarticle),
  FOREIGN KEY(tva_idtva)
    REFERENCES tva(idtva)
      ON DELETE NO ACTION
      ON UPDATE CASCADE,
  FOREIGN KEY(famille_idfamille)
    REFERENCES famille(idfamille)
      ON DELETE NO ACTION
      ON UPDATE CASCADE,
  FOREIGN KEY(unite_idunite)
    REFERENCES unite(idunite)
      ON DELETE NO ACTION
      ON UPDATE CASCADE
);



CREATE TABLE utilisateur (
  login VARCHAR(25) NOT NULL,
  pass VARCHAR(15) NOT NULL,
  class CHAR(1) NOT NULL,
  etat CHAR(1) NOT NULL,
  PRIMARY KEY(login)
);

FactProforma.java://「FactureProforma」は「proformainvoice」です

public class FactProforma implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "IDFACT_PROFORMA", nullable = false)
    private Integer idfactProforma;
    @Basic(optional = false)
    @Column(name = "DATE", nullable = false)
    @Temporal(TemporalType.DATE)
    private Date date;
    @OneToMany(cascade=CascadeType.ALL , mappedBy = "factProforma")
    private List<FactProformaHasArticle> factProformaHasArticleList;
    @JoinColumn(name = "UTILISATEUR_LOGIN", referencedColumnName = "LOGIN", nullable = false)
    @ManyToOne(optional = false)
    private Utilisateur utilisateurLogin;
    @JoinColumn(name = "CLIENT_IDCLIENT", referencedColumnName = "IDCLIENT", nullable = false)
    @ManyToOne(optional = false)
    private Client clientIdclient;

FactProformaHasArticle.java

public class FactProformaHasArticle implements Serializable {
    private static final long serialVersionUID = 1L;
    @EmbeddedId
    protected FactProformaHasArticlePK factProformaHasArticlePK;
    @Basic(optional = false)
    @Column(name = "PRIX_HT", nullable = false)
    private double prixHt;
    @Basic(optional = false)
    @Column(name = "QTE", nullable = false)
    private double qte;
    @Basic(optional = false)
    @Column(name = "REMISE", nullable = false)
    private double remise;
    @Basic(optional = false)
    @Column(name = "MARGE_BENEF", nullable = false)
    private double margeBenef;
    @JoinColumn(name = "FACT_PROFORMA_IDFACT_PROFORMA", referencedColumnName = "IDFACT_PROFORMA", nullable = false, insertable = false, updatable = false)
    @ManyToOne(optional = false)
    private FactProforma factProforma;
    @JoinColumn(name = "ARTICLE_IDARTICLE", referencedColumnName = "IDARTICLE", nullable = false, insertable = false, updatable = false)
    @ManyToOne(optional = false)
    private Article article;

FactProformaHasArticlePK.java

@Embeddable
public class FactProformaHasArticlePK implements Serializable {
    @Basic(optional = false)
    @Column(name = "FACT_PROFORMA_IDFACT_PROFORMA", nullable = false)
    private int factProformaIdfactProforma;
    @Basic(optional = false)
    @Column(name = "ARTICLE_IDARTICLE", nullable = false, length = 40)
    private String articleIdarticle;

私のコード:

FactProforma factpro=new FactProforma(null, new Date());
 Utilisateur user=new Utilisateur(loginActuel);
 Client client=new Client(Integer.parseInt(codeClient.getText()));

java.util.List<FactProformaHasArticle> ListOfArticles =this.c.GetPanier(dtm,factpro);

factpro.setClientIdclient(client);
factpro.setFactProformaHasArticleList(ListOfArticles);
factpro.setUtilisateurLogin(user);

 EntityManager em= emf.createEntityManager();
    em.getTransaction().begin();

    em.persist(factpro);

    em.getTransaction().commit();

スタックトレース:

Exception in thread "AWT-EventQueue-0" javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "CONSTRAINT_9A: PUBLIC.FACT_PROFORMA_HAS_ARTICLE FOREIGN KEY(FACT_PROFORMA_IDFACT_PROFORMA) REFERENCES PUBLIC.FACT_PROFORMA(IDFACT_PROFORMA)"; SQL statement:
Internal Exception: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "CONSTRAINT_9A: PUBLIC.FACT_PROFORMA_HAS_ARTICLE FOREIGN KEY(FACT_PROFORMA_IDFACT_PROFORMA) REFERENCES PUBLIC.FACT_PROFORMA(IDFACT_PROFORMA)"; SQL statement:
INSERT INTO TEST.PUBLIC.FACT_PROFORMA_HAS_ARTICLE (MARGE_BENEF, PRIX_HT, QTE, REMISE, ARTICLE_IDARTICLE, FACT_PROFORMA_IDFACT_PROFORMA) VALUES (?, ?, ?, ?, ?, ?) [23506-164]
INSERT INTO TEST.PUBLIC.FACT_PROFORMA_HAS_ARTICLE (MARGE_BENEF, PRIX_HT, QTE, REMISE, ARTICLE_IDARTICLE, FACT_PROFORMA_IDFACT_PROFORMA) VALUES (?, ?, ?, ?, ?, ?) [23506-164]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
    at org.h2.message.DbException.get(DbException.java:169)
    at org.h2.message.DbException.get(DbException.java:169)
    at org.h2.message.DbException.get(DbException.java:146)
    at org.h2.message.DbException.get(DbException.java:146)
    at org.h2.constraint.ConstraintReferential.checkRowOwnTable(ConstraintReferential.java:345)
    at org.h2.constraint.ConstraintReferential.checkRowOwnTable(ConstraintReferential.java:345)
    at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:287)
    at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:287)
    at org.h2.table.Table.fireConstraints(Table.java:862)
    at org.h2.table.Table.fireConstraints(Table.java:862)
    at org.h2.table.Table.fireAfterRow(Table.java:879)
    at org.h2.table.Table.fireAfterRow(Table.java:879)
    at org.h2.command.dml.Insert.insertRows(Insert.java:126)
    at org.h2.command.dml.Insert.update(Insert.java:84)
    at org.h2.command.dml.Insert.insertRows(Insert.java:126)
    at org.h2.command.CommandContainer.update(CommandContainer.java:73)
    at org.h2.command.dml.Insert.update(Insert.java:84)
    at org.h2.command.Command.executeUpdate(Command.java:226)
    at org.h2.command.CommandContainer.update(CommandContainer.java:73)
    at org.h2.server.TcpServerThread.process(TcpServerThread.java:325)
    at org.h2.command.Command.executeUpdate(Command.java:226)
    at org.h2.server.TcpServerThread.run(TcpServerThread.java:146)
    at java.lang.Thread.run(Thread.java:722 at org.h2.server.TcpServerThread.process(TcpServerThread.java:325)
)

Error Code: 23506
Call: INSERT INTO TEST.PUBLIC.FACT_PROFORMA_HAS_ARTICLE (MARGE_BENEF, PRIX_HT, QTE, REMISE, ARTICLE_IDARTICLE, FACT_PROFORMA_IDFACT_PROFORMA) VALUES (?, ?, ?, ?, ?, ?)
    at org.h2.server.TcpServerThread.run(TcpServerThread.java:146)
    bind => [6 parameters bound]
    at java.lang.Thread.run(Thread.java:722)

明日は、競合を避けるために、別のDBMSを試してみます...

PS:フランス語でごめんなさい..私には選択の余地がありません。

更新:その動作:

EntityManager em= emf.createEntityManager();
    em.getTransaction().begin();

    em.persist(fact);
    em.flush();

    for(FactProformaHasArticle couple: estComposeFacture)
    {
        couple.getFactProformaHasArticlePK().setFactProformaIdfactProforma(fact.getIdfactProforma());
        em.persist(couple);
    }

    em.getTransaction().commit();
4

2 に答える 2

1

編集された投稿:FactProformaHasArticleとFactProformaの関係が完全に参照されていることを確認する必要があります。持続する前に、このようなものが必要だと思います。

List<FactProformaHasArticle> ListOfArticles =this.c.GetPanier(dtm,factpro)
for(FactProformaHasArticle fpha: ListOfArticles) {
  fpha.setFactProforma(factpro);
}

(注:メンバー変数の最初の文字を小文字にすると、たとえば などlistOfArticlesの代わりに なりますListOfArticles

INITIAL POST(あなたの場合にも有効な場合):主キーの注釈からoptional=falseとを削除しようとしましたか?nullable=false以前は問題がありました。そのため、JPAでは許可されませんMyEntity me=new MyEntity(null);でした。次のようなものを試してください:

public class FactProforma implements Serializable {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  // removed:@Basic(optional = false)
  @Column(name = "IDFACT_PROFORMA") // removed: , nullable = false)
  private Integer idfactProforma;
  // rest should be ok
}
于 2012-06-29T01:23:38.797 に答える
1

すでに解決策がありますが、それが機能する理由は、EmbeddedId の基本的なマッピングを介して制御される主キー フィールドがあるためだと思います。そのため、永続化する前に関係を設定したとしても、pk フィールドは null になります。 embeddedId の articleIdarticle に値が手動で設定されるまで。これは、「ARTICLE_IDARTICLE」が 2 回マッピングされている場合の問題です。両方のマッピングをアプリケーションで維持する必要があり、FactProformaHasArticle を永続化する前に pk 値を使用できる必要があります。

JPA 2.0 では、リレーションシップで @MapsId アノテーションを使用して、embeddedId の基本的なマッピングを制御していることを示すことができるため、この設定が少し簡単になります。そのため、リレーションシップを設定し、JPA にフィールドを設定させるだけで済みます。または、ここで説明されているように、embeddedId を削除し、オブジェクトを PKclass として使用して、@Id との関係を直接マークすることもできます。

http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#JPA_2.0 JPA が pk 値を設定するため、これを使用するとフラッシュ呼び出しを削除できます。

于 2012-07-03T15:14:48.677 に答える