Jpa 持久化多对一类时违反外键约束

Jpa 持久化多对一类时违反外键约束,jpa,ejb,eclipselink,Jpa,Ejb,Eclipselink,尝试持久化多对一实体时出错: 内部异常:org.postgresql.util.PSQLException:错误:表“concept”的插入或更新违反外键约束“concept\u concept\u class\u fk” 详细信息:表“概念类”中不存在键(概念类id)=(概念)。 错误代码:0 调用:插入概念(概念密钥、描述、标签、代码、概念类id)值(?,,,?,?) bind=>[27,描述1,标签1,代码1,概念] 查询:InsertObjectQuery(com.mirth.resul

尝试持久化多对一实体时出错:

内部异常:org.postgresql.util.PSQLException:错误:表“concept”的插入或更新违反外键约束“concept\u concept\u class\u fk” 详细信息:表“概念类”中不存在键(概念类id)=(概念)。 错误代码:0 调用:插入概念(概念密钥、描述、标签、代码、概念类id)值(?,,,?,?) bind=>[27,描述1,标签1,代码1,概念] 查询: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;
    }

}
此外,重要的是正在生成的sql:

在概念类(id、oid、描述、标签)中插入值(?,?,?)bind=>[LOINC\u测试,2.16.212.31.231.54,这是LOINC\u测试的元数据文件,LOINC\u测试]

在概念(概念密钥、描述、标签、代码、概念类id)中插入值(?、、、?、?)bind=>[27,描述1,标签1,代码1,概念


失败的原因很明显:它为概念类id插入了单词概念。它应该插入单词LOINC\u TEST。我不明白它为什么用这个词。我使用调试器查看了Concept和ConceptClass实例,它们都不包含这个词。我用的是eclipselink。有人知道为什么会这样吗

列概念\u类\u id有两个相互冲突的定义

列概念\类\ id出现在类概念周围的@DiscriminatorColumn和@JoinColumn注释中。你不能那样做。这两个注释正在争夺表概念中列概念\类\ id的控制权@“鉴别器”栏目恰好获胜。这就是为什么类名“Concept”出现在SQL绑定中,您希望在该绑定中有一个ConceptClass id

顺便说一下,@DiscriminatorColumn仅在多个类共享一个表时才有用。@D/C记录a类行代表的类别。如果概念表中仅存储类概念的对象,则可以删除@DiscriminatorColumn@除非一个表中有多个类,否则D/C是没有意义的

总而言之,修复包括:

  • 在概念的@DiscriminatorColumn注释中更改“name”
  • 更改Concept.conceptClass的@JoinColumn注释中的“name”
  • 删除类概念上的@DiscriminatorColumn注释

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