我应该如何通过对列表进行重新排序(添加和删除)来进行更新,然后使用Hibernate @OneToMany和@OrderColumn将其保存回数据库中?
文档没有对此问题保持沉默,我发现唯一的解决方案对我来说很la脚。
这是我的实体:
@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);
}
因此,在这里基本上我清空了原始列表,然后按照我需要的顺序重新插入更新后剩下的内容。许多其他尝试以另一种方式进行更新的尝试均失败了。
问题是,我可以以智能方式进行操作吗?说,仅删除已删除的内容,在更新位置更新顺序,并仅插入新内容? 当然,我可以按索引删除并在列表的末尾插入,但是这些基本操作还不足以对整个列表进行重新排序。
有可能吗?
谢谢!
答案 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<>();