休眠:@OrderColumn,添加和删除后重新插入

时间:2018-06-28 08:53:55

标签: java hibernate

我应该如何通过对列表进行重新排序(添加和删除)来进行更新,然后使用Hibernate @OneToMany和@OrderColumn将其保存回数据库中?

文档没有对此问题保持沉默,我发现唯一的解决方案对我来说很la脚。

这是一个数据库片段:enter image description here

这是我的实体:

@Entity
@Table(name="channel")
public class Channel {
    @Id
    @GeneratedValue(strategy= GenerationType.AUTO, generator="native")
    @GenericGenerator(name = "native", strategy = "native")
    @Column(name="channel_id")
    private Long channelId;

    @Column(name="name")
    private String name;

    @OneToMany(mappedBy = "channel", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @OrderColumn(name = "sequence_order")
    private List<Programme> programmes = new ArrayList<>();

    public void addProgramme(Programme programme) {
        programmes.add(programme);
        programme.setChannel(this);
    }
}

@Entity
@Table(name="programme")
public class Programme {
    @Id
    @GeneratedValue(strategy= GenerationType.AUTO, generator="native")
    @GenericGenerator(name = "native", strategy = "native")
    @Column(name="prog_id")
    private Long progId;

    @Column(name="name")
    private String name;

    @Column(name="type")
    private String type;

    @Column(name="sequence_order")
    private int order;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="channel_id")
    private Channel channel;
}

我正在使用Spring Data JpaRepositories进行基本操作。 现在,我正在填充一些运行良好的数据:

   @Test
    public void saveTest() {
        Channel channel = new Channel();
        channel.setName("France24");

        Programme programme = new Programme();
        programme.setName("L'enfants show");
        programme.setChannel(channel);
        programme.setType("entertainment");

        Programme programme2 = new Programme();
        programme2.setName("France News");
        programme2.setChannel(channel);
        programme2.setType("news");

        Programme programme3 = new Programme();
        programme3.setName("Holidays in Paris");
        programme3.setChannel(channel);
        programme3.setType("movie");

        Programme programme4 = new Programme();
        programme4.setName("FIFA Cup 2018");
        programme4.setChannel(channel);
        programme4.setType("sport");

        channel.setProgrammes(Arrays.asList(programme, programme2, programme3, programme4));
        channelDao.save(channel);
    }

接下来是带有重新排序以及插入和删除操作的更新:

// Working solution
@Commit
@Test
public void updateTest() {
    Channel channel = channelDao.findById(1L).get();
    channel.getProgrammes().clear();
    channelDao.flush();

    Programme programme2 = new Programme();
    programme2.setName("France News");
    programme2.setChannel(channel);
    programme2.setType("news");

    Programme programme3 = new Programme();
    programme3.setName("Holidays in Paris");
    programme3.setChannel(channel);
    programme3.setType("movie");

    Programme programme4 = new Programme();
    programme4.setName("FIFA Cup 2018");
    programme4.setChannel(channel);
    programme4.setType("sport");

    Programme programme5 = new Programme();
    programme5.setName("Music show");
    programme5.setChannel(channel);
    programme5.setType("show");

    channel.addProgramme(programme5);
    channel.addProgramme(programme4);
    channel.addProgramme(programme3);
    channel.addProgramme(programme2);
}

因此,在这里基本上我清空了原始列表,然后按照我需要的顺序重新插入更新后剩下的内容。许多其他尝试以另一种方式进行更新的尝试均失败了。

问题是,我可以以智能方式进行操作吗?说,仅删除已删除的内容,在更新位置更新顺序,并仅插入新内容? 当然,我可以按索引删除并在列表的末尾插入,但是这些基本操作还不足以对整个列表进行重新排序。

有可能吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

在休眠状态下,列表保持插入顺序(在您的情况下为progId)。您可以对提交的订单使用@OrderBy批注。因此,当获取Channel时,它将获得Program并按顺序排序。

 @OneToMany(mappedBy = "channel", cascade = CascadeType.ALL, fetch = 
            FetchType.EAGER, orphanRemoval = true)
@OrderBy("order ASC")
private List<Programme> programmes = new ArrayList<>();