2010-04-11 47 views
1

試圖堅持多對一實體時,我得到一個錯誤:違反外鍵約束堅持時多到一個

Internal Exception: org.postgresql.util.PSQLException: ERROR: insert or update on table "concept" violates foreign key constraint "concept_concept_class_fk" Detail: Key (concept_class_id)=(Concept) is not present in table "concept_class". Error Code: 0 Call: INSERT INTO concept (concept_key, description, label, code, concept_class_id) VALUES (?, ?, ?, ?, ?) bind => [27, description_1, label_1, code_1, Concept] Query: InsertObjectQuery(com.mirth.results.entities.Concept[conceptKey=27]) at com.sun.ejb.containers.BaseContainer.checkExceptionClientTx(BaseContainer.java:3728) at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:3576) at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1354) ... 101 more

這是一種嘗試堅持它的方法。我已經把一個註釋,其中行是:

@Override 
public void loadConcept(String metaDataFilePath, String dataFilePath) throws Exception { 
    try { 
     ConceptClassMetaData conceptClassMetaData = (ConceptClassMetaData) ModelSerializer.getInstance().fromXML(FileUtils.readFileToString(new File(metaDataFilePath), "UTF8")); 


     em.executeNativeQuery(conceptClassMetaData.getCreateStatement()); 

     ConceptClassRow conceptClassRow = conceptClassMetaData.getConceptClassRow(); 

     ConceptClass conceptClass = em.findByPrimaryKey(ConceptClass.class, conceptClassRow.getId()); 
     if (conceptClass == null) { 
      conceptClass = new ConceptClass(conceptClassRow.getId()); 
     } 
     conceptClass.setLabel(conceptClassRow.getLabel()); 
     conceptClass.setOid(conceptClassRow.getOid()); 
     conceptClass.setDescription(conceptClassRow.getDescription()); 

     conceptClass = em.merge(conceptClass);    

     DataParser dataParser = new DataParser(conceptClassMetaData, dataFilePath); 
     for (ConceptModel conceptModel : dataParser.getConceptRows()) { 
      ConceptFilter<Concept> filter = new ConceptFilter<Concept>(Concept.class); 
      filter.setCode(conceptModel.getCode()); 
      filter.setConceptClass(conceptClass.getLabel()); 
      List<Concept> concepts = em.findAllByFilter(filter); 

      Concept concept = new Concept(); 
      if (concepts != null && !concepts.isEmpty()) { 
       concept = concepts.get(0); 
      } 
      concept.setCode(conceptModel.getCode()); 
      concept.setDescription(conceptModel.getDescription()); 
      concept.setLabel(conceptModel.getLabel()); 
      concept.setConceptClass(conceptClass); 
      concept = em.merge(concept); //THIS LINE CAUSES THE ERROR! 

     } 
    } catch (Exception e) {    
     e.printStackTrace(); 
     throw e; 
    } 

} 

...

下面是如何在兩個實體的定義:

@Entity 
@Table(name = "concept") 
@Inheritance(strategy=InheritanceType.JOINED) 
@DiscriminatorColumn(name="concept_class_id", discriminatorType=DiscriminatorType.STRING) 
public class Concept extends KanaEntity { 
    @Id 
    @Basic(optional = false) 
    @Column(name = "concept_key") 
    protected Integer conceptKey; 
    @Basic(optional = false) 
    @Column(name = "code") 
    private String code; 
    @Basic(optional = false) 
    @Column(name = "label") 
    private String label; 
    @Column(name = "description") 
    private String description; 
    @JoinColumn(name = "concept_class_id", referencedColumnName = "id") 
    @ManyToOne 
    private ConceptClass conceptClass; 

... 


@Entity 
@Table(name = "concept_class") 
public class ConceptClass extends KanaEntity { 
    @Id 
    @Basic(optional = false) 
    @Column(name = "id") 
    private String id; 
    @Basic(optional = false) 
    @Column(name = "label") 
    private String label; 
    @Column(name = "oid") 
    private String oid; 
    @Column(name = "description") 
    private String description; 
.... 

而且也,重要的是這是在SQL正在生成:

INSERT INTO concept_class (id, oid, description, label) VALUES (?, ?, ?, ?) bind => [LOINC_TEST, 2.16.212.31.231.54, This is a meta data file for LOINC_TEST, loinc_test]

INSERT INTO concept (concept_key, description, label, code, concept_class_id) VALUES (?, ?, ?, ?, ?) bind => [27, description_1, label_1, code_1, Concept]

這是失敗的原因很明顯:它插入單詞Concept_class_id的概念。它應該插入單詞LOINC_TEST。我無法弄清楚它爲什麼使用這個詞。我使用調試器來查看Concept和ConceptClass實例,它們都不包含這個詞。我正在使用eclipselink。有誰知道爲什麼會發生這種情況?

回答

0

您對列concept_class_id有兩個衝突的定義。

concept_class_id列出現在類Concept的@DiscriminatorColumn和@JoinColumn註釋中。你不能那樣做。這兩個註釋正在爭取控制表概念中的列concept_class_id。 @DiscriminatorColumn恰好贏得勝利。這就是爲什麼類名「Concept」出現在您希望獲得ConceptClass ID的SQL綁定中的原因。

順便說一下,@DiscriminatorColumn僅在多個類共享單個表時纔有用。 @ D/C記錄一行代表的類別。如果只有Concept類的對象存儲在概念表中,則可以刪除@DiscriminatorColumn。除非表中有多個類,否則@ D/C是毫無意義的。

總之,修復包括:

  • 阿爾特 「名」 在概念的@DiscriminatorColumn註釋
  • 阿爾特 「名」 在Concept.conceptClass的@JoinColumn註解
  • 階級概念
  • 刪除@DiscriminatorColumn註釋

HTH