Сохранение графа глубоких объектов с JPA без em.flush () - PullRequest
2 голосов
/ 15 сентября 2010

У меня есть следующая модель:

Отчет , ReportSection и ReportSectionProperty .

Отчет имеет ноль ко многим ReportSections , ReportSection имеет ноль ко многим ReportSectionPropert -ies.Это будет квалифицироваться как трехуровневый граф объектов.

Я создаю новый Отчет , затем добавляю к нему несколько разделов и добавляю к нему некоторые свойства.Когда я пытаюсь сохранить Report , я получаю следующую ошибку:

Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: ERROR: insert or update on table "report_section" violates foreign key constraint "fk_report_section_report"
  Detail: Key (id_node)=(186) is not present in table "report". {prepstmnt 20859482 INSERT INTO core.report_section (index_section, name, report_section_type, id_node) VALUES (?, ?, ?, ?) [params=?, ?, ?, ?]} [code=0, state=23503]

Итак, OpenJPA сохраняет граф объектов, но каким-то образом он начался с середины.id_node 186 действительно является следующим идентификатором таблицы Report, но очевидно, что объект не сохраняется при сохранении ReportSection.

Если я добавлю em.persist (report), то em.flush () между каждой операциейдобавляя разделы или свойства, все работает.Так ли это?

Если я не добавляю какие-либо свойства в разделы, постоянный Отчет работает даже без em.flush ().

Я использую OpenJPA 2.0.3 в качестве JPAПоставщик.


Может быть, некоторые соответствующие части кода:

Report.java

public class Report{

    @OneToMany(targetEntity = ReportSection.class, cascade = CascadeType.ALL, mappedBy="report")
    private List reportSections;

    public void addReportSection(ReportSection section){
        synchronized (this) {
            if (getReportSections() == null)
                reportSections = new ArrayList();
            reportSections.add(section);
            section.setReport(this);
        }
    }
}

ReportSection.java

public class ReportSection{

    @ManyToOne
    @JoinColumn(name="id_node")
    private Report report;

    @OneToMany(targetEntity=ReportSectionProperty.class, cascade=CascadeType.ALL,   mappedBy="reportSection")
    private List reportSectionProperties;

    public void setReport(Report report) {
        this.report = report;
    }

    public void addReportSectionProperty(ReportSectionProperty reportSectionProperty){
        synchronized (this) {
            if (getReportSectionProperties() == null)
                reportSectionProperties = new ArrayList();
            reportSectionProperties.add(reportSectionProperty);
            reportSectionProperty.setReportSection(this);
        }
    }
}

ReportSectionProperty

public class ReportSectionProperty{

    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="id_report_section")
    private ReportSection reportSection;

    public void setReportSection(ReportSection reportSection) {
        this.reportSection = reportSection;
    }
}

Ответы [ 3 ]

1 голос
/ 04 марта 2011

Это может быть мертвая тема, но, поскольку я столкнулся с подобной проблемой, я хотел бы показать, как мне удалось ее решить, для будущих ссылок (в случае, если потерянная душа столкнется с OpenJPA)

Попробуйте установить это свойство в свой файл persistence.xml, чтобы OpenJPA мог переставить оператор SQL в правильном порядке.

property name = "openjpa.jdbc.SchemaFactory" value = "native (ForeignKeys = true)"

http://openjpa.apache.org/faq.html#FAQ-CanOpenJPAreorderSQLstatementstosatisfydatabaseforeignkeyconstraints%253F

0 голосов
/ 20 ноября 2011

Вы пытались добавить cascade = ALL к отношению @ManyToOne из ReportSection в Report?

Может также помочь опубликовать ваше свойство @Id в родительском объекте Report.

0 голосов
/ 15 сентября 2010

Если я поставлю em.persist (report), то em.flush () между каждой операцией добавления разделов или свойств, все работает.Так ли это?

В этом не должно быть необходимости при правильных настройках каскадирования и правильно построенных двунаправленных ассоциациях (за исключением, конечно, ошибки поставщика JPA).Первая часть выглядит хорошо.Но я бы хотел посмотреть, как ты справляешься с последней частью.

...