Я получаю сообщение об ошибке при попытке сохранить сущность «многие в один»:
Внутреннее исключение: org.postgresql.util.PSQLException: ОШИБКА: вставка или обновление таблицы «concept» нарушает ограничение внешнего ключа «concept_concept_class_fk»
Подробно: Ключ (concept_class_id) = (Concept) отсутствует в таблице "concept_class".
Код ошибки: 0
Вызов: INSERT INTO concept (concept_key, description, label, code, concept_class_id) VALUES (?,?,?,?,?)
bind => [27, description_1, label_1, code_1, Concept]
Запрос: InsertObjectQuery (com.mirth.results.entities.Concept [conceptKey = 27])
в com.sun.ejb.containers.BaseContainer.checkExceptionClientTx (BaseContainer.java:3728)
на com.sun.ejb.containers.BaseContainer.postInvokeTx (BaseContainer.java:3576)
на com.sun.ejb.containers.BaseContainer.postInvoke (BaseContainer.java:1354)
... еще 101
Вот метод, который пытается сохранить его. Я положил комментарий, где строка:
@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;
}
}
* +1009 * ...
Вот как определяются две сущности:
@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, Это файл метаданных для 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 для concept_class_id. Следует вставить слово LOINC_TEST . Я не могу понять, почему он использует это слово. Я использовал отладчик для просмотра Concept и экземпляра ConceptClass, и ни один из них не содержит этого слова. Я использую eclipselink. Кто-нибудь знает, почему это происходит?