![](/img/trans.png)
[英]Bad order on embeded list annotated with @ElementCollection and @OrderColumn
[英]How to change the order of an ordered list with JPA and @OrderColumn?
我有两个实体类,调色板和颜色——一个调色板包含一个有序的颜色列表。 但是,当我尝试更改列表的顺序(交换两种颜色)时,我会导致异常,因为我(暂时)复制了唯一键。
实体类(我使用 Spring Boot + JPA + Lombok)定义为:
@Entity
@Table(name = "colourPalette")
public class Palette {
@Getter
@Setter
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", nullable = false)
private Integer id;
@Getter
@Setter
@Column(unique = true)
private String paletteName;
@Getter
@OneToMany
@OrderColumn(name="colourIndex")
private List<Colour> colourList = new ArrayList<>();
// other fields removed
}
@Entity
@Table(name = "paletteColour")
public class Colour {
@Getter
@Setter
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", nullable = false)
private Long id;
@Getter
@Setter
@Column(nullable = false)
private int colourIndex;
// other fields removed
}
我可以轻松地创建调色板和颜色,并将颜色添加到调色板:
Optional<Palette> paletteOptional = paletteDB.findById(paletteID);
if (paletteOptional.isPresent()) {
Palette p = paletteOptional.get();
Colour c = new Colour();
c.setColourIndex(p.getColourList().size());
// set other fields in the colour object
p.getColourList().add(c);
colourDB.save(c);
paletteDB.save(p);
}
但是重新排序列表失败,试图简单地交换集合的顺序
Optional<Palette> optionalPalette = paletteDB.findById(paletteID);
if (optionalPalette.isPresent() && optionalPalette.get().getColourList().size()>1
) {
Palette p = optionalPalette.get();
Collections.swap(p.getColourList(),0,1);
paletteDB.save(p);
}
返回 JdbcSQLIntegrityConstraintViolationException:唯一索引或主键违规
手动更新颜色索引的值也是如此
Colour c1 = p.getColourList().get(0);
Colour c2 = p.getColourList().get(1);
Collections.swap(p.getColourList(),0,1);
c1.setColourIndex(1);
c2.setColourIndex(0);
colourDB.save(c1);
colourDB.save(c2);
paletteDB.save(p);
看第二个选项,很明显为什么。 但是这样做的正确方法是什么?
我可以给你一些可能有帮助的一般性建议。 一般来说,我不会手动更改由 hibernate 管理的集合中元素的顺序。 相反,我建议只向其中添加/删除元素。 想想你的底层数据库:为你的用例重新排列表中记录的顺序是否有意义? 而不是。
我不知道为什么您需要在调色板中对 colors 进行特定排序,但让我们想象一下,您需要排序来对前端进行一些优先级排序(例如,调色板列表中的第一种颜色应该显示在屏幕左侧,例如在coolors.co上)。 那么我会推荐以下数据库model。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.