有没有理由使用同步集合初始化实体属性?

Are*_*rff 1 java jpa eclipselink

对于我工作的项目中的JPA-Entities,List或Map类型的属性总是初始化为同步实现Vector和Hashtable.
(Unsynchronized ArrayList和HashMap是Java中的标准实现,除非真的需要同步.)

有谁知道为什么需要同步收藏?我们使用EclipseLink.


当我问起这件事时,没有人知道为什么这样做.它似乎总是像这样完成.也许这是旧版EclipseLink所需要的?


我问的原因有两个:

  • 我更喜欢像其他地方一样使用标准实现ArrayList和HashMap.如果那是安全的.
  • JDK中没有匹配的同步Set实现.至少不是EclipseLink所期望的可序列化的.

示例实体:

@Entity
public class Person {
    ...

    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable( ... )
    private List<Role> accessRoles;


    @ElementCollection
    @CollectionTable( ... )
    @MapKeyColumn(name="KEY")
    @Column(name="VALUE")
    private Map<String, String> attrs;

    public Person() {
        // Why Vector/Hashtable instead of ArrayList/HashMap?
        accessRoles = new Vector<Role>();
        attrs = new Hashtable<String, String>();
    }

    public List<Role> getAccessRoles() {
        return accessRoles;
    }

    public void setAccessRoles(List<Role> accessRoles) {
        this.accessRoles = accessRoles;
    }

    public Map<String, String> getAttrs() {
        return attrs;
    }

    public void setAttrs(Map<String, String> attrs) {
        this.attrs = attrs;
    }
}
Run Code Online (Sandbox Code Playgroud)

flu*_*lup 5

通常不需要Vector和更常用的ArrayList.因此,如果您当前的代码库中充满了Vector,这有点代码味道,确保您的团队成员知道差异是明智的.另请参见ArrayList和Vector之间的区别是什么?为什么Java的Vector类被认为已经过时或被弃用?

这并不意味着你应该进行大清理并用ArrayLists替换现有代码中的所有向量.

  • 您的代码使用列表,编程时您不会注意到一个区别.
  • 预期的唯一优势是提高性能.
  • 很难判断您的代码是否都不依赖于Vector提供的同步.

因此,除非您目前遇到性能问题,或者明确(重新)设计整个代码库的同步,否则您可能会很难修复并发错误而没有任何好处.

此外,请注意,当多个线程同时访问您的集合时,性能会受到使用向量的影响最大.所以,如果你从性能遭受损失,并决定更换载体出于这个原因,你需要非常小心,以保持足够的访问同步.


编辑:你特别询问EclipseLink JPA.

如果他们要求你使用Vectors和Hashtables,这将是相当令人惊讶的,因为这意味着他们要求你依赖过时的数据结构.在他们的例子中,他们使用ArrayLists和HashMaps,因此我们可以得出结论,确实不是这种情况.

更具体地潜入源代码,我们可以看到他们的CollectionContainerPolicy使用Collection接口而不关心集合的实现.但是,当您的内部集合类是Vector时,它确实有特殊情况.请参阅buildContainerFromVector.它的默认容器类是Vector,尽管你可以改变它.

另请参阅Container策略的文档.

EclipseLink和您的列表相遇的最具侵入性的时刻是您懒得加载集合.EclipseLink将使用自己的IndirectList替换集合,该集合在内部使用Vector.看看jpa返回什么样的集合?因此,在这些情况下,EclipseLink将始终为您提供Vector(!),甚至在集合初始化中指定的集合也无关紧要.

因此,EclipseLink确实偏好使用向量,并且使用带有EclipseLink的向量意味着将对象引用从一个集合复制到另一个集合.