Hibernate/JPA中@ElementCollection如果没有@OrderColumn性能会降低

19-02-15 banq
         

@ElementCollection是Hibernate/JPA中代表父子关系的多方注释,但是没有@OrderColumn的@ElementCollection插入和删除容易出现性能损失,而使用@OrderColumn性能变得更好。

本应用程序展示了没有@OrderColumn使用@ElementCollection可能导致的性能损失。

父实体:

@Entity
public class ShoppingCart implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    
    @ElementCollection
    private List<String> products = new ArrayList<>();

这里的@ElementCollection并没有主键,@ElementCollection是映射到单独的数据表中。当你有很多插入和删除动作时,避免@ElementCollection,因为数据库为了实现加入或删除,得删除很多现有的行。数据表中数据项越多,性能损失越大。

测试源代码可以在这里找到  。

解决

通过添加@OrderColumn可以减少在集合尾部附近进行操作时的一些性能损失(例如,在集合末尾添加/删除)。主要是,位于添加/删除条目之前的所有元素都保持不变,因此如果我们影响靠近集合尾部的行,则可以忽略性能损失。

@Entity
public class ShoppingCart implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name", nullable = false)
    private String name;
    
    @ElementCollection
    @OrderColumn(name = "index_no")
    private List<String> products = new ArrayList<>();

测试源代码可以在这里找到