Hibernate: @OrderColumn, вставьте заново с добавлением и удалением - PullRequest
0 голосов
/ 28 июня 2018

Как я должен обновить, переупорядочив (с добавлением и удалением) список и сохранив его обратно в БД с Hibernate @OneToMany и @OrderColumn?

В документации по этому вопросу ничего не сказано, и единственное решение, которое я нашел, кажется мне неубедительным.

Вот фрагмент БД: 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 голосов
/ 28 июня 2018

В спящем режиме List поддерживает порядок вставки, который я имею в виду в вашем случае progId. Вы можете использовать аннотацию @OrderBy с поданным заказом. Поэтому при получении канала он получит программу и отсортирует по порядку.

 @OneToMany(mappedBy = "channel", cascade = CascadeType.ALL, fetch = 
            FetchType.EAGER, orphanRemoval = true)
@OrderBy("order ASC")
private List<Programme> programmes = new ArrayList<>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...