Foreign Key constraint violation when persisting a many-to-one class

Posted by tieTYT on Stack Overflow See other posts from Stack Overflow or by tieTYT
Published on 2010-04-11T06:20:47Z Indexed on 2010/04/11 6:33 UTC
Read the original article Hit count: 408

Filed under:
|
|

I'm getting an error when trying to persist a many to one entity:

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

Here is the method that tries to persist it. I've put a comment where the line is:

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

}

...

Here are how the two entities are defined:

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

And also, what's important is the sql that's being generated:

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]

The reason this is failing is obvious: It's inserting the word Concept for the concept_class_id. It should be inserting the word LOINC_TEST. I can't figure out why it's using this word. I've used the debugger to look at the Concept and the ConceptClass instance and neither of them contain this word. I'm using eclipselink. Does anyone know why this is happening?

© Stack Overflow or respective owner

Related posts about ejb

Related posts about jpa