I keep a list of Strings in SQL as @ElementCollection, my main usage is similar to a Queue:
- fetch it from the database
- run some calculations
- remove the first element and insert a new element to the end of the list:
this.measurements.remove(0); this.measurements.add(measurement);
- save it to the database
The problem with the current implementation is that removing the first element updates the index of all elements in the list (items_order column) which is very bad for performance… Is there any other way to do this? perhaps is it possible to have a running index (items_order column) so order will be kept but not position in list?
Example:
left to ‘:’ is the index of the element and to the right is the element itself.
[0:”a”, 1:”b”, 2:”c”]
After Calculation the following will be inserted to the database:
[0:”b”, 1:”c”, 2:”d”] – all element indexes have been updated (bad performance)
Possible solution which i’m not sure if possible to implement:
[1:”b”, 2:”c”, 3:”d”] – all elements keep the same order id (still ordered)
My entity:
@Entity public class Store { @ElementCollection @OrderColumn private List<String> items; // setter getter }
Advertisement
Answer
What I ended up doing was creating an entity of my own instead of using annotations to create the fields table, this is the Store entity:
@Entity public class Store { @OneToMany(cascade=CascadeType.ALL, orphanRemoval=true) @OrderBy("index ASC") private List<Item> itemsList; @Column private int index = 0; public List<Item> getItemsList() { return itemsList; } public void setItemsList(List<Item> itemsList) { this.itemsList = itemsList; } public void addToItemList(String item) { final Item newItem = new Item(); newItem.setStoreId(this.id); newItem.setValue(item); newItem.setIndex(index++); this.itemsList.add(newItem); } }
this is the Item entity which the store will hold a list of:
@Entity @IdClass(Ids.class) public class Item { @Id private long storeId; @Id private int index; @Column private String value; public long getStoreId() { return storeId; } public void setStoreId(long storeId) { this.storeId = storeId; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } } class Ids implements Serializable { // each id will be composed of storeId + index long storeId; int index; }