@ElementCollection Java 持久性(休眠)导致重复实例加载

2022-09-04 21:28:26

使用@ElementCollection时,全部加载就是加载对象的多个实例。更具体地说,它为集合OfStrings中的每个元素加载一个实例。

例如,如果数据库具有一个 MyClass 实例,其中包含 collectionOfStrings.size() == 4,则调用加载所有 MyClass 值将返回大小为 4 的列表(所有相同的对象),而不仅仅是 1 个对象。

有没有一种干净而简单的方法来解决这个问题,或者行为是预期的?

// Parent class is a @MappedSuperclass which may or may not be relevant to the issue
@Entity
public class MyClass extends ParentClass {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @ElementCollection(fetch=FetchType.EAGER)
    @IndexColumn(name="indexColumn")
    private List<String> collectionOfStrings;

    // other instance variables, constructors, getters, setters, toString, hashcode and equals
}

public class MyClassDAO_Hibernate extends GenericHibernateDAO<MyClass, Long> implements MyClassDAO {

    @Override
    public List<MyClass> loadAll() {
        List<MyClass> entityList = null;
        Session session = getSession();
        Transaction trans = session.beginTransaction();
        entityList = findByCriteria(session);
        trans.commit();
        return entityList;
    }

}

protected List<T> findByCriteria(Session session, Criterion... criterion) {
    Criteria crit = session.createCriteria(getPersistentClass());
    for (Criterion c : criterion) {
        crit.add(c);
    }
    return crit.list();
}

MyClassDAO myClassDAO = new MyClassDAO_Hibernate(); // in reality, implementation type is determined with a Factory
...
List<MyClass> myClassInstances = myClassDAO.loadAll();

谢谢,HeavyE

编辑:添加了 findByCriteria 调用。


答案 1

我不确定这是一个错误还是合法行为,但可以通过应用结果转换器来修复它:DISTINCT_ROOT_ENTITY

protected List<T> findByCriteria(Session session, Criterion... criterion) {
    Criteria crit = session.createCriteria(getPersistentClass());
    for (Criterion c : criterion) {
        crit.add(c);
    }
    crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
    return crit.list();
}

答案 2

仅当热切地获取集合时,才会观察到这种情况。Hibernate 将此注释映射转换为外部联接查询,这会导致每个链接集合OfString 元素的根元素列表中出现多个。

有关此确切问题,请参阅休眠 ORM 问题跟踪器中的票证 HHH-6783。显然没有解决方案。:-(

此处还提供了指向 Hibernate FAQ 的链接,该常见问题解答涉及外部连接的问题。

我正在处理完全相同的问题。在我的情况下,使用@ElementCollection是有意义的,但不会以审查我的所有数据访问层实现为代价。该怎么办?


推荐