EAGER和分页:Spring MVC + JPA Repository + Hibernate

时间:2017-03-29 10:18:01

标签: hibernate spring-mvc spring-data-jpa eager

我有实体A ,其关系@OneToMany实体B (fetch mode = EAGER)权利A 在LAZY中也与其他实体有其他关系,但对此问题并不重要。

实体B 实体A 的关系@ManyToOne(fech mode = EAGER)。 功能B LAZY与其他实体之间也存在其他关系,但对此问题并不重要。

稍后,我有一个实现JpaRepository类的接口,我在其中定义了一个@Query,在其他实体之间有一些内连接,用于获得10个项目的实体A 的计算得分,使用Page和Pageable元素。

此过程失败。为什么呢?

我的数据库中实体A的表有+1000个寄存器,条件为@query。但是在Hibernate或JPA返回10个实体A之前,在内部执行1000多个选择以获取实体B数据(EAGER realation)并进行探索。

为什么不获得10个实体A和执行10"选择"仅获得10个实体B?

独特的解决方案是改变我从EAGER到LAZY的关系?不能使用EAGER进行分页?

为什么会这样?任何解决方案?

修改 aclaration:+1000 entityA +1000 entityB(在我的例子中,一个entityA只有一个entityB,但entityA可以有多个实体B)

@Entity
@Table(name="EntityA")
public class EntityA implements Serializable{

    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    @Column(columnDefinition = "BINARY(16)")
    private UUID id;

    @OneToMany(mappedBy="entityA", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @OrderBy("updatedDate DESC")
    private Set<EntityB> entitiesB = new HashSet<EntityB>();

    ...
}

@Entity
@Table(name="EntityB")
public class EntityB implements Serializable{

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    @Column(columnDefinition = "BINARY(16)")
    private UUID id;

    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "idEntityA", nullable = false)
    private EntityA entityA;

    ...
}

public interface EntityA_DAO  extends JpaRepository<EntityA, UUID>{
    @Query("SELECT DISTINCT a FROM EntityA a INNER JOIN a.entityB b LEFT JOIN b.scoreEntityB s INNER JOIN a.user u INNER JOIN a.properties p INNER JOIN p.category c " +
            "WHERE c.cod IN (:codcats) AND a.user <> :user AND b.codState = '001' AND a.codState NOT IN ('002','004','005') AND p.deleted <> 1 " +
            "GROUP BY b ORDER BY a.createdDate DESC, COUNT(s) DESC")
    public Page<EntityA> findAllByCategories(@Param("user") User user, @Param("codcats") List<Integer> lstCodCats,  Pageable pageable);
}

编辑2

这是我的跟踪错误的片段,重复并重复相同:

  

at java.util.HashMap.put(Unknown Source)at   java.util.HashSet.add(未知来源)at   java.util.AbstractCollection.addAll(未知来源)at   org.hibernate.collection.internal.PersistentSet.endRead(PersistentSet.java:327)     在   org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:234)     在   org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:221)     在   org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:194)     在   org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerImpl.endLoading(CollectionReferenceInitializerImpl.java:154)     在   org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishLoadingCollections(AbstractRowReader.java:249)     在   org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:212)     在   org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:123)     在   org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:122)     在   org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86)     在   org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:167)     在   org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3956)     在   org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:508)     在   org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:478)     在   org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219)     在   org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:116)     在   org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:89)     在org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1129)     在   org.hibernate.internal.SessionImpl.immediateLoad(SessionImpl.java:997)     在   org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:157)     在   org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:266)     在   org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:68)     在   com.treebuk.model.Fragment _ _ $$ jvsta55_10.hashCode(片段_ _ $$ jvsta55_10.java)     在com.treebuk.model.Fragment.hashCode(Fragment.java:210)at   sun.reflect.GeneratedMethodAccessor111.invoke(未知来源)at   sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源)at   java.lang.reflect.Method.invoke(未知来源)at   org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:79)     在   com.treebuk.model.Fragment _ _ $$ jvsta55_10.hashCode(片段_ _ $$ jvsta55_10.java)     在com.treebuk.model.TextFragment.hashCode(TextFragment.java:340)at   java.util.HashMap.hash(未知来源)at   java.util.HashMap.put(未知来源)at   java.util.HashSet.add(未知来源)at   java.util.AbstractCollection.addAll(未知来源)at   org.hibernate.collection.internal.PersistentSet.endRead(PersistentSet.java:327)     在   org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:234)     在   org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:221)     在   org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:194)     在   org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerImpl.endLoading(CollectionReferenceInitializerImpl.java:154)     在   org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishLoadingCollections(AbstractRowReader.java:249)     在   org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:212)     在   org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:123)     在   org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:122)     在   org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86)     在   org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:167)     在   org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3956)     在   org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:508)     在   org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:478)     在   org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219)     在   org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:116)     在   org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:89)     在org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1129)     在   org.hibernate.internal.SessionImpl.immediateLoad(SessionImpl.java:997)     在   org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:157)     在   org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:266)     在   org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:68)     在   com.treebuk.model.Fragment _ _ $$ jvsta55_10.hashCode(片段_ _ $$ jvsta55_10.java)     在com.treebuk.model.Fragment.hashCode(Fragment.java:210)at   sun.reflect.GeneratedMethodAccessor111.invoke(未知来源)at   sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源)at   java.lang.reflect.Method.invoke(未知来源)at   org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:79)     在   com.treebuk.model.Fragment _ _ $$ jvsta55_10.hashCode(片段_ _ $$ jvsta55_10.java)     在com.treebuk.model.TextFragment.hashCode(TextFragment.java:340)at   java.util.HashMap.hash(未知来源)

1 个答案:

答案 0 :(得分:0)

Finnaly,我发现了问题。问题是方法实体B hasCode(),这个方法与实体A进行了比较,然后当Spring尝试获取元素时,执行hascode方法,并进入无限循环。我更改了hascode()和equal()方法来删除这些比较(在我的情况下不是必需的)。