Foreign Key constraint when persisting a many-to-one class
- by tieTYT
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?