首页 > 解决方案 > Hibernate:@OrderColumn,添加删除重新插入

问题描述

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

文档对这个问题保持沉默,我发现的唯一解决方案对我来说似乎很蹩脚。

这是一个数据库片段:在此处输入图像描述

这是我的实体:

@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);
}

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

问题是,我能以聪明的方式做到这一点吗?说,只删除已删除的内容,更新已更新的顺序,并仅插入新的内容?当然,我可以按索引删除并在列表末尾插入,但是在重新排序整个列表时,这些基本操作是不够的。

有可能吗?

谢谢!

标签: javahibernate

解决方案


在休眠中,列表维护插入顺序,我的意思是在您的情况下是 progId。您可以将 @OrderBy 注释与订单归档一起使用。因此,当获取 Channel 时,它将获取 Program 并按顺序排序。

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

推荐阅读