Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jpa EclipseLink批取提示不适用于两个字段_Jpa_Eclipselink_Spring Data Jpa - Fatal编程技术网

Jpa EclipseLink批取提示不适用于两个字段

Jpa EclipseLink批取提示不适用于两个字段,jpa,eclipselink,spring-data-jpa,Jpa,Eclipselink,Spring Data Jpa,我在SpringDataJPA中使用QueryHits来使用EclipseLink批处理获取,类型为in。最终,我需要在30个字段左右使用它,但在2个字段中它似乎不起作用。字段A有多个关系,字段B有多个关系。根据初始查询的结果,我希望批处理提示生成一个IN子句,其中字段A有2个ID,字段B有12个ID。当每次为一个字段打开提示时,这可以正常工作。当两个字段都启用时,提示仅适用于查询提示列表中最后一个提示的字段。我曾试着在黑暗中急切而懒惰地在田野上打球,但没有效果 基于关系类型混合批取提示是否有限

我在SpringDataJPA中使用QueryHits来使用EclipseLink批处理获取,类型为in。最终,我需要在30个字段左右使用它,但在2个字段中它似乎不起作用。字段A有多个关系,字段B有多个关系。根据初始查询的结果,我希望批处理提示生成一个IN子句,其中字段A有2个ID,字段B有12个ID。当每次为一个字段打开提示时,这可以正常工作。当两个字段都启用时,提示仅适用于查询提示列表中最后一个提示的字段。我曾试着在黑暗中急切而懒惰地在田野上打球,但没有效果

基于关系类型混合批取提示是否有限制?有什么不同吗?EclipseLink文档对此功能不是很详细

编辑:似乎我只启用哪个字段并不重要,它一次只对一个字段有效。下面是两个实体的示例代码。
BaseEntity
定义PK id的生成

@Entity
@Table(name = "MainEntity")
public class MainEntity extends BaseEntity implements Cloneable {

    ...


    @ManyToMany(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST)
    @JoinTable(
            name="EntityBMapping",
            joinColumns={@JoinColumn(name="mainId", referencedColumnName="id")},
            inverseJoinColumns={@JoinColumn(name="bId", referencedColumnName="id")})
    @JsonIgnore
    private Set<EntityB> bSet = new HashSet<>();

    @ManyToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
    @JoinTable(
            name="EntityAMapping",
            joinColumns={@JoinColumn(name="mainId", referencedColumnName="id")},
            inverseJoinColumns={@JoinColumn(name="aId", referencedColumnName="id")})
    @JsonIgnore
    @OrderColumn(name="order_index", columnDefinition="SMALLINT")
    private List<EntityA> aList = new ArrayList<>();

    ...

}

@Entity
@Cache(type=CacheType.FULL)
@Table(name = "EntityA")
public class EntityA extends BaseEntity {

@Column(name = "name", columnDefinition = "VARCHAR(100)")
private String name;

@ManyToMany(mappedBy = "entityASet", fetch=FetchType.LAZY)
@JsonIgnore
private Set<MainEntity> mainEntityList = new HashSet<>();

}



@Entity
@Cache(type=CacheType.FULL)
@Table(name = "EntityB")
public class EntityB extends BaseEntity {

@Column(name = "name", columnDefinition = "VARCHAR(100)")
private String name;

@ManyToMany(mappedBy = "entityBSet", cascade=CascadeType.ALL)
@JsonIgnore
private Set<MainEntity> mainEntityList = new HashSet<>();

}

正如Chris提到的,命名查询是解决此问题的最佳方法。另一个选项是使用自定义存储库,并为每个指定的提示自己在EntityManager上调用setHint(有很多在SpringDataJPA中创建自定义repo的示例)。您可以尝试覆盖
SimpleParepository上的
findOne(…)
protected TypedQuery getQuery(规范规范规范、类域类、排序)
,尝试创建一种通用方法来正确设置提示,但您可能需要检查
getQuery(…)上的提示设置是否重复
因为您仍然需要为此调用super(),然后在返回查询之前应用其他提示。我不确定如果应用重复的提示,行为会是什么。省去麻烦,使用命名查询是我的建议

您提到您正在30个字段上使用它;它是否在同一实体/查询中处理其他实体/查询?显示您的实体、查询和生成的SQL语句。添加了代码-什么字段似乎无关紧要,它一次只处理一个字段。它似乎完全忽略了除最后一个字段之外的任何批处理获取提示。如果我将o.aList更改为o.a.List.id或o.iDontExist之类的无效内容,则不会出现错误。我想当你设置提示时,它会一直覆盖上一个,直到它到达最后一个,而不是合并它们。有没有办法为多个批处理获取字段设置提示?您必须检查spring数据是如何创建查询的。我猜它是通过一个映射一次将所有提示传递给查询。如果要调用setHint(“eclipselink.batch”、“o.bSet”)、setHint(“eclipselink.batch”、“o.aList”),它会起作用,但是因为Spring正在构建一个映射,只有最后一个被传递到JPA查询。另一种方法是在实体中构建一个命名查询,指定它的提示,然后使用Spring来调用它。我检查了源代码,事实上这就是Spring所做的。我开了一张JIRA的票。我来试试看。感谢您的帮助。有关信息,此错误最近已在Spring data中修复(不知道Spring data jpa的确切版本,但Spring boot 2.4及更高版本允许使用相同名称的多个查询提示)
@QueryHints(value = {
            @QueryHint(name = org.eclipse.persistence.config.QueryHints.BATCH_TYPE, value = "IN"),
            @QueryHint(name = org.eclipse.persistence.config.QueryHints.BATCH_SIZE, value = "250"),
            @QueryHint(name = org.eclipse.persistence.config.QueryHints.BATCH, value = "o.aList")},
            @QueryHint(name = org.eclipse.persistence.config.QueryHints.BATCH, value = "o.bSet")},  
    forCounting = false)
    List<MainEntity> findAll(Specification spec);
SELECT id, STATUS, user_id FROM MainEntity WHERE ((STATUS = ?) OR ((STATUS = ?) AND (user_id = ?)))--bind => [ONESTAT, TWOSTAT, myuser]
..
SELECT t1.id, t1.name, t0.order_index FROM EntityAMapping t0, EntityA t1 WHERE ((t0.mainId = ?) AND (t1.id = t0.aId))--bind => [125e17d2-9327-4c6b-a65d-9d0bd8c040ac]
...
SELECT t1.id, t1.name, t0.mainId FROM EntityBMapping t0, EntityB t1 WHERE ((t1.id = t0.bId) AND (t0.mainId IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)))--bind => [125e17d2-9327-4c6b-a65d-9d0bd8c040ac, 1c07a3a9-7028-48ba-abe8-2296d58ebd57, 235bb4f2-d724-4237-b73b-725db2b9ca9f, 264f64b3-c355-4476-8530-11d2037b1f3c, 2d9a7044-73b3-491d-b5f1-d5b95cbb1fab, 31621c93-2b0b-4162-9e42-32705b7ba712, 39b33b19-c333-4523-a5a7-4ba0108fe9de, 40ba7706-4023-4b7e-9bd5-1641c5ed6498, 52eed760-9eaf-4f6a-a36f-076b3eae9297, 71797f0c-5528-4588-a82c-5e1d4d9c2a66, 89eda2ef-80ff-4f54-9e6a-cf69211dfa61, 930ba300-52fa-481c-a0ae-bd491e7dc631, 96dfadf9-2490-4584-b0d4-26757262266d, ae079d02-b0b5-4b85-8e6f-d3ff663afd6e, b2974160-33e8-4faf-ad06-902a8a0beb04, b86742d8-0368-4dde-8d17-231368796504, caeb79ce-2819-4295-948b-210514376f60, cafe838f-0993-4441-8b99-e012bbd4c5ee, da378482-27f9-40b7-990b-89778adc4a7e, e4d7d6b9-2b8f-40ab-95c1-33c6c98ec2ee, e557acf4-df01-4e66-9d5e-84742c99870d, ef55a83c-2f4c-47b9-99bb-6fa2f5c19a76, ef55a83c-2f4c-47b9-99bb-6fa2f5c19a77]
...
SELECT t1.id, t1.name, t0.order_index FROM EntityAMapping t0, EntityA t1 WHERE ((t0.mainId = ?) AND (t1.id = t0.aId))--bind => [1c07a3a9-7028-48ba-abe8-2296d58ebd57]