1

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

实体 B@ManyToOne也与实体 A有关系(fech 模式 = EAGER)。实体 B也与其他实体有其他关系LAZY,但对于这个问题并不重要。

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

这里这个过程失败了。为什么?

我在数据库中的实体 A 表有 +1000 个具有条件的寄存器@query。但在 Hibernate 或 JPA 向我返回 10 个实体 A 之前,在内部执行 1000 多个选择以获取实体 B 数据(EAGER 真实性)和 explote。

为什么不获取 10 个实体 A 并执行 10 个“选择”以获得 10 个实体 B?

独特的解决方案是将我的关系从 EAGER 更改为 LAZY?不能与 EAGER 一起工作?

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

编辑: 声明:+1000 entityA +1000 entityB(在我的示例中,一个 entityA 只有一个 entityB,但 entityA 可以有多个 entityB)

@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

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

在 java.util.HashMap.put(Unknown Source) at java.util.HashSet.add(Unknown Source) at java.util.AbstractCollection.addAll(Unknown Source) at org.hibernate.collection.internal.PersistentSet.endRead(PersistentSet .java:327) 在 org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:221) 在 org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:234) 在 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) at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:122) at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader. java:86) 在 org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3956) 在 org.hibernate.event 的 org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:167) .internal.DefaultLoadEventListener。loadFromDatasource(DefaultLoadEventListener.java:508) at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:478) at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219) at 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(Fragment_$$_jvsta55_10.java) 在 com.treebuk.model.Fragment.hashCode(Fragment.java: 210) 在 sun.reflect.GeneratedMethodAccessor111.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.hibernate.proxy.pojo.javassist .JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:79) 在 com.treebuk.model.Fragment_$$_jvsta55_10.hashCode(Fragment_$$_jvsta55_10.java) 在 com.treebuk.model.TextFragment.hashCode(TextFragment.java:340) 在java.util.HashMap.hash(Unknown Source) at java.util.HashMap.put(Unknown Source) at java.util.HashSet.add(Unknown Source) at java.util。AbstractCollection.addAll(Unknown Source) at org.hibernate.collection.internal.PersistentSet.endRead(PersistentSet.java:327) at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:234) at 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 (默认加载事件监听器。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) at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:266) at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:在 com.treebuk.model.Fragment_$$_jvsta55_10。com.treebuk.model.Fragment.hashCode(Fragment.java:210) 的 hashCode(Fragment_$$_jvsta55_10.java) sun.reflect.GeneratedMethodAccessor111.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)在 java.lang.reflect.Method.invoke(Unknown Source) 在 org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:79) 在 com.treebuk.model.Fragment_$$_jvsta55_10.hashCode(Fragment_ $$_jvsta55_10.java) at com.treebuk.model.TextFragment.hashCode(TextFragment.java:340) at java.util.HashMap.hash(Unknown Source)Method.invoke(Unknown Source) at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:79) at com.treebuk.model.Fragment_$$_jvsta55_10.hashCode(Fragment_$$_jvsta55_10.java) at com.treebuk.model.TextFragment.hashCode(TextFragment.java:340) at java.util.HashMap.hash(Unknown Source)Method.invoke(Unknown Source) at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:79) at com.treebuk.model.Fragment_$$_jvsta55_10.hashCode(Fragment_$$_jvsta55_10.java) at com.treebuk.model.TextFragment.hashCode(TextFragment.java:340) at java.util.HashMap.hash(Unknown Source)

4

1 回答 1

0

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

于 2017-03-30T18:03:15.807 回答