gpt4 book ai didi

hibernate - Hibernate 中的条件 api 查询不存在

转载 作者:行者123 更新时间:2023-12-02 02:08:59 25 4
gpt4 key购买 nike

我正在尝试编写查询,它会返回未分配给路线的司机列表。

我的数据库设置如下。

Route:
route_id
user_id//specified as driver

User:
user_id
role // need to select user, which is Driver role

只有路线能看到用户(司机),用户(司机)看不到路线。

这是我尝试编写这样的查询。

public List<User> getUnsignedDrivers(){
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

CriteriaQuery<User> query = criteriaBuilder.createQuery(User.class);
Root<User> user = query.from(User.class);
query.select(user);

Subquery<Route> subquery = query.subquery(Route.class);
Root<Route> subRootEntity = subquery.from(Route.class);
Predicate correlatePredicate = criteriaBuilder.equal(subRootEntity.get("Route_.User"), user);
subquery.where(correlatePredicate);
query.where(criteriaBuilder.not(criteriaBuilder.exists(subquery)));

TypedQuery<User> typedQuery = entityManager.createQuery(query);
return typedQuery.getResultList();
}

我是 jpa 的新手,所以这就是问题所在。

更具体地说,我需要选择没有设置任何路由的角色驱动程序的用户

我的实体设置如下:

    @Entity
public class Route {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@OneToOne(fetch = FetchType.EAGER, cascade = {})
@JoinColumn(name = "user_id", nullable = true)
private User driver;
.....
@Entity
public class User {

public static enum Role {
ADMIN, MANAGER, DRIVER;
}

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

@Enumerated(EnumType.STRING)
@Column(nullable = false)
private Role role;

更新:当前查询

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

CriteriaQuery<User> query = criteriaBuilder.createQuery(User.class);
Root<User> user = query.from(User.class);
Predicate predicateRole = criteriaBuilder.equal(user.get("role"), User.Role.DRIVER);
query.where(predicateRole);
query.select(user);


Subquery<Route> subquery = query.subquery(Route.class);
Root<Route> subRootEntity = subquery.from(Route.class);
Predicate correlatePredicate = criteriaBuilder.equal(subRootEntity.get("driver"), user);
subquery.where(correlatePredicate);
query.where(criteriaBuilder.not(criteriaBuilder.exists(subquery)));

TypedQuery<User> typedQuery = entityManager.createQuery(query);
return typedQuery.getResultList();

问题依然存在

我得到这个异常:

java.lang.IllegalStateException: No explicit selection and an implicit one cold not be determined
at org.hibernate.ejb.criteria.QueryStructure.locateImplicitSelection(QueryStructure.java:296)
at org.hibernate.ejb.criteria.QueryStructure.render(QueryStructure.java:249)
at org.hibernate.ejb.criteria.CriteriaSubqueryImpl.render(CriteriaSubqueryImpl.java:282)
at org.hibernate.ejb.criteria.predicate.ExistsPredicate.render(ExistsPredicate.java:58)
at org.hibernate.ejb.criteria.QueryStructure.render(QueryStructure.java:258)
at org.hibernate.ejb.criteria.CriteriaQueryImpl.render(CriteriaQueryImpl.java:340)
at org.hibernate.ejb.criteria.CriteriaQueryCompiler.compile(CriteriaQueryCompiler.java:217)
at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:587)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
at $Proxy25.createQuery(Unknown Source)

在这一行抛出 TypedQuery<User> typedQuery = entityManager.createQuery(query);

解决方法这对我很有效。我写这个是因为我不能使用反向关系。

public List<User> getUnsignedDrivers(){
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

CriteriaQuery<User> query = criteriaBuilder.createQuery(User.class);
Root<User> user = query.from(User.class);
Predicate predicateRole = criteriaBuilder.equal(user.get("role"), User.Role.DRIVER);
query.where(predicateRole);
query.select(user);

TypedQuery<User> typedQuery = entityManager.createQuery(query);
List<User> allDrivers = typedQuery.getResultList();
List<User> notAssignedDrivers = new ArrayList<User>();
List<Route> haveDriverRoutes = getRouteWithNoDrives();
for (User driver : allDrivers){
if (!isDriverAssigned(haveDriverRoutes,driver.getId())){
notAssignedDrivers.add(driver);
}
}
return notAssignedDrivers;
}

private boolean isDriverAssigned(List<Route> haveDriverRoutes, long driverId){
for(Route route : haveDriverRoutes){
if (route.getDriver().getId() == driverId){
return true;
}
}
return false;
}

@SuppressWarnings("unchecked")
public List<Route> getRouteWithNoDrives() {
Query query = entityManager.createQuery("SELECT o FROM " + type.getSimpleName() + " o WHERE o.driver != null");
return query.getResultList();
}

最佳答案

您在 User 实体中缺少反向 OneToOne 关系:

@OneToOne(mappedBy="driver")
private Route route;

参见 this link关于如何映射 OneToOne 关系。

你在这部分有一个错误:subRootEntity.get("Route_.User")。这不是有效的语法,并且您在 Route 实体中没有名为 User 的属性:该属性名为 driver(阅读后你最近的编辑)。

你有两种方法可以得到 Path表达式,要么使用:

Path<User> path = subRootEntity.get("driver");
// in a compact way:
Predicate correlatePredicate = criteriaBuilder.equal(subRootEntity.get("driver"), user);

或通过使用元模型:

Path<User> path = subRootEntity.get(Route_.driver);
// in a compact way:
Predicate correlatePredicate = criteriaBuilder.equal(subRootEntity.get(Route_.driver), user);

您似乎混合了这两种方法。看这个article有关使用元模型的更多信息。

查询的其余部分看起来是正确的。

关于hibernate - Hibernate 中的条件 api 查询不存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13752405/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com