使JPA中的级联持久存在与一对多关系中的集合相同的顺序

时间:2014-07-29 15:45:59

标签: jpa one-to-many cascade

我有一些名为ExperimentExperimentSetupExperimentResults的JPA(EclipseLink)实体。 Experiment实体与ExperimentSetup具有一对多关系,ExperimentSetupExperimentResult具有一对多关系。如果Experiment被保留ExperimentSetupExperimentResults也应该保留。为此,我使用CascadeType.PERSIST注释中的@OneToMany设置。它确实持有我想要的对象,但是按照我预期的不同顺序(这是在ArrayList中表示实体一对多关系的顺序)。

所以我想知道的是,是否有一种方法可以使实体按照它们在集合中的顺序插入到数据库中,同时仍然使用CascadeType.PERSIST?

我的课程(简化):

@Entity
public class Experiment implements Serializable {
    @Id
    private String eid;
    @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, mappedBy = "expEID")
    private List<ExperimentSetup> setupList;
    @Column
    private String name;    

    Getters and setter...
}

@Entity
public class ExperimentSetup implements Serializable {
        @Id
        private String id;
        @OneToMany(mappedBy = "setupId",cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
        private List<ExperimentResults> results;
        @Column
        private Integer setupValue;

        Getters and setter...
}

@Entity
public class ExperimentResults implements Serializable {
            @Id
            private String id;
            @Columns Integer data;

            Getters and setter...
}

1 个答案:

答案 0 :(得分:1)

根据您评论中的信息,我声明您不应该依赖于广告订单。如果没有&#39; ORDER BY&#39;在检索时无法保证广告订单的顺序。条款。在JPA中,这转换为@OrderBy或@OrderColumn注释。

我建议使用@OrderColumn的解决方案,而不是按指定的顺序插入。您的表必须将订单信息保存在新列中。最好的部分是JPA将负责为您维护此专栏。为@OneToMany关系添加其他注释。例如:

@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, mappedBy = "expEID")
@OrderColumn(name="SETUP_ORDER")
private List<ExperimentSetup> setupList;

通过此示例,您必须在SETUP_ORDER上添加其他列(ExperimentSetup)。

<强>更新 好的,打印机和PrintJobs的示例可能更直观。

@Entity
public class Printer {
    @Id
    @GeneratedValue
    int id;
    @OneToMany(mappedBy = "printer", cascade = {CascadeType.PERSIST})
    @OrderColumn(name="PRINT_ORDER")
    List<PrintJob> jobs;
}

@Entity
public class PrintJob {
    @Id
    @GeneratedValue
    int id;

    String name;

    @ManyToOne
    Printer printer;

    public PrintJob(){}
    public PrintJob(String n, Printer p) {
        this.name = n;
        this.printer = p;
    }
}

 Printer p = new Printer();
 p.jobs = new ArrayList<PrintJob>();
 p.jobs.add(new PrintJob("A", p));
 p.jobs.add(new PrintJob("B", p));
 p.jobs.add(new PrintJob("C", p));
 em.persist(p);

这会产生:

> SELECT * FROM Printer
ID         
-----------
1          
> SELECT * FROM PrintJob
ID  |NAME  |PRINTER_ID |PRINT_ORDER
-----------------------------------
2   |A     |1          |0          
3   |B     |1          |1          
4   |C     |1          |2