简体   繁体   中英

How to change the order of an ordered list with JPA and @OrderColumn?

I have two entity classes, Palette and Colour – a palette contains an ordered list of colours. However when I try and change the order of the list (swap two colours) I cause exceptions because I'm (temporarily) duplicating unique keys.

The entity classes (I'm using Spring Boot + JPA + Lombok) are defined as:

@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

}

I can easily create palettes and colours and add a colour to a palette with:

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

But re-ordering the list fails, trying to simply swap the order of the collection

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

Returns JdbcSQLIntegrityConstraintViolationException: Unique index or primary key violation

So too does manually updating the value of colour index

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

Looking at the second option, it's obvious why. But what is the right way of doing this?

I can give you some general advice that may help. In general I would not mess with manually altering the order of elements in a collection managed by hibernate. Instead I recommend only to add/remove elements to/from it. Think about your underlying database: Would it make sense to rearrange the ordering of the records in the table for your use case? Rather not .

I don't know why you need a certain ordering of the colors in the palette, but let us just imagine that you need the ordering to do some prioritization on the fronend (for example the first color in your palette list should be displayed far on the left of the screen, such as on coolors.co ). Then I would recommend the following database model.

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM