Spring 数据 JPA + JpaSpecificationExecutor + NamedEntityGraph
Spring Data JPA + JpaSpecificationExecutor + NamedEntityGraph
我有两个实体。 Parent 和 Child。
@Entity
public class Parent {
@Id
@Column(name = "PARENT_ID")
private BigInteger id;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "LAST_NAME")
private String lastName;
}
@Entity
@NamedEntityGraph(name = "Child.parentObj", attributeNodes = @NamedAttributeNodes("parentObj"))
public class Child{
//blah blah blah
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="PARENT_ID")
Parent parentObj;
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name="CHILD_ID")
Set<Address> address
//blah blah blah
}
ChildRepository.java
public interface ChildRepository extends JpaRepository<T, ID>, JpaSpecificationExecutor<T>{
@EntityGraph(value="Child.parentObj")
public List<Child> findAll(Specification<Child> spec);
}
我正在尝试按条件查找 child 个实体,它应该始终具有 parent。
我在尝试在地址 table.
中查找 parentObj 时遇到异常
Caused by: org.hibernate.QueryException: could not resolve property: parentObj of: com.xxx.Address [..]
我找到了这个 link 并尝试了 Joep 给出的解决方案但同样的错误。
Spring Data JPA + JpaSpecificationExecutor + EntityGraph
我错过了什么。我无法理解 why/how 我限制在 Child Object 中寻找 parentObj 因为地址没有引用 Parent.
我正在通过 Address.street 进行搜索。
我也试过 ad-hoc 实体图。异常:
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.QueryException: could not resolve property: parentObj of: com.xxx.Address
Caused by: org.hibernate.QueryException: could not resolve property: parentObj of: com.xxx.Address
at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:83)
at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:77)
at org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:1978)
at org.hibernate.hql.internal.ast.tree.FromElementType.getPropertyType(FromElementType.java:367)
at org.hibernate.hql.internal.ast.tree.FromElement.getPropertyType(FromElement.java:500)
at org.hibernate.engine.query.spi.EntityGraphQueryHint.getFromElements(EntityGraphQueryHint.java:95)
at org.hibernate.engine.query.spi.EntityGraphQueryHint.toFromElements(EntityGraphQueryHint.java:68)
at org.hibernate.hql.internal.ast.HqlSqlWalker.processQuery(HqlSqlWalker.java:676)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:665)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.collectionFunctionOrSubselect(HqlSqlBaseWalker.java:4905)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.comparisonExpr(HqlSqlBaseWalker.java:4606)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2104)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2029)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2029)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:796)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:597)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
... 60 more
您正在使用 Child.parentObj
作为实体图名称,但您将实体图命名为 Child.parent
。使用
@EntityGraph(value="Child.parent")
没有@NamedEntityGraph
我们可以定义一个ad-hoc实体图,不用@NamedEntityGraph就可以使用
@EntityGraph(attributePaths = {"parentObj"})
更新:
实体图和规范都不能一起工作。
有一种方法可以解决这个问题。不要 eager for parent fetch child only first then make a list of child ids from child's and get parents using in clause query使用 child 个 ID。总共只需要 2 个查询。如果您想使用 1 个查询解决此问题,请使用 DSL 进行原始查询。
我想通过条件搜索找到子项并为每个子项获取 ParentObj。我想为家长加入而不是个人 select。我试图通过使用 EntityGraph 来解决这个问题,但它没有用。正如@EKlavya 指出的那样,Specification 和 EntityGraph 不能一起工作。
我解决的方法是:
root.fetch("parentObj", JOIN.LEFT);
在我的 toPredicate 方法中。这将在 1 个查询中获得带有父实体的子实体。
我有两个实体。 Parent 和 Child。
@Entity
public class Parent {
@Id
@Column(name = "PARENT_ID")
private BigInteger id;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "LAST_NAME")
private String lastName;
}
@Entity
@NamedEntityGraph(name = "Child.parentObj", attributeNodes = @NamedAttributeNodes("parentObj"))
public class Child{
//blah blah blah
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="PARENT_ID")
Parent parentObj;
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name="CHILD_ID")
Set<Address> address
//blah blah blah
}
ChildRepository.java
public interface ChildRepository extends JpaRepository<T, ID>, JpaSpecificationExecutor<T>{
@EntityGraph(value="Child.parentObj")
public List<Child> findAll(Specification<Child> spec);
}
我正在尝试按条件查找 child 个实体,它应该始终具有 parent。
我在尝试在地址 table.
中查找 parentObj 时遇到异常Caused by: org.hibernate.QueryException: could not resolve property: parentObj of: com.xxx.Address [..]
我找到了这个 link 并尝试了 Joep 给出的解决方案但同样的错误。
Spring Data JPA + JpaSpecificationExecutor + EntityGraph
我错过了什么。我无法理解 why/how 我限制在 Child Object 中寻找 parentObj 因为地址没有引用 Parent.
我正在通过 Address.street 进行搜索。
我也试过 ad-hoc 实体图。异常:
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.QueryException: could not resolve property: parentObj of: com.xxx.Address
Caused by: org.hibernate.QueryException: could not resolve property: parentObj of: com.xxx.Address
at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:83)
at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:77)
at org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:1978)
at org.hibernate.hql.internal.ast.tree.FromElementType.getPropertyType(FromElementType.java:367)
at org.hibernate.hql.internal.ast.tree.FromElement.getPropertyType(FromElement.java:500)
at org.hibernate.engine.query.spi.EntityGraphQueryHint.getFromElements(EntityGraphQueryHint.java:95)
at org.hibernate.engine.query.spi.EntityGraphQueryHint.toFromElements(EntityGraphQueryHint.java:68)
at org.hibernate.hql.internal.ast.HqlSqlWalker.processQuery(HqlSqlWalker.java:676)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:665)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.collectionFunctionOrSubselect(HqlSqlBaseWalker.java:4905)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.comparisonExpr(HqlSqlBaseWalker.java:4606)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2104)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2029)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2029)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:796)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:597)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
... 60 more
您正在使用 Child.parentObj
作为实体图名称,但您将实体图命名为 Child.parent
。使用
@EntityGraph(value="Child.parent")
没有@NamedEntityGraph
我们可以定义一个ad-hoc实体图,不用@NamedEntityGraph就可以使用
@EntityGraph(attributePaths = {"parentObj"})
更新: 实体图和规范都不能一起工作。 有一种方法可以解决这个问题。不要 eager for parent fetch child only first then make a list of child ids from child's and get parents using in clause query使用 child 个 ID。总共只需要 2 个查询。如果您想使用 1 个查询解决此问题,请使用 DSL 进行原始查询。
我想通过条件搜索找到子项并为每个子项获取 ParentObj。我想为家长加入而不是个人 select。我试图通过使用 EntityGraph 来解决这个问题,但它没有用。正如@EKlavya 指出的那样,Specification 和 EntityGraph 不能一起工作。
我解决的方法是:
root.fetch("parentObj", JOIN.LEFT);
在我的 toPredicate 方法中。这将在 1 个查询中获得带有父实体的子实体。