从 OneToMany 关系中提取记录的 Hibernate Criteria
Hibernate Criteria to pull records from OneToMany Relations
我正在传递一组车辆名称,例如 ['car','jeep','truck','bike']
,并希望 select 使用条件查询在此列表中拥有 vehicles
的车主,这里的车主可以拥有多个 vahicles
(一对多)。我有一个限制,我需要使用 Criteria 查询。
class Owner {
@ID
@GeneratedValue(strategy = IDENTITY)
@Column(name = "owner_id")
private Long ownerId;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "owner_id")
private Set<Vehicles> vehicles;
}
class Vehicles {
@ID
@GeneratedValue(strategy = IDENTITY)
@Column(name = "vehicle_id")
private Long vehicleId;
@ManyToOne
@JoinColumn(name = "owner_id")
private Owner owner;
@Column(name="vehicle_name")
private String vehicleName;
}
以下是我尝试过但没有成功的方法
Criteria criteria = getSession().createCriteria(Owner.class);
criteria.createAlias("vehicles", "vehicles");
criteria.add(Restrictions.in("vehicles.vehicleName", setOfVehicles));
criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
首先,您的映射看起来不正确。 Owner
和 Vehicles
之间存在双向关联。因此,只有 @ManyToOne
侧应该用 @JoinColumn
注释。我将使用以下方式更正映射:
@Entity
@Table
public class Owner
{
@Id
@Column(name = "own_id")
private Long id;
@OneToMany(mappedBy = "owner")
private Set<Vehicles> vehicles;
}
@Entity
@Table
public class Vehicles
{
@Id
@Column(name = "veh_id")
private Long id;
@Column(name = "veh_name")
private String name;
@ManyToOne
@JoinColumn(name = "veh_own_id")
private Owner owner;
}
接下来我要强调的是,您尝试使用已弃用的 Hibernate org.hibernate.Criteria
API. I am going to provide an example for the Criteria API。因此,查询将具有以下视图:
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Owner> criteria = builder.createQuery(Owner.class);
Root<Owner> root = criteria.from(Owner.class);
SetJoin<Owner, Vehicles> vehs = (SetJoin<Owner, Vehicles>) root.fetch(Owner_.vehicles);
criteria
.select(root)
.distinct(true)
.where(
vehs.get(Vehicles_.NAME).in(Arrays.asList("car", "jeep", "truck", "bike"))
);
List<Owner> deps = session.createQuery(criteria).getResultList();
Owner_
和 Vehicles_
类 属于所谓的 JPA static metamodel. Why the casting (SetJoin<Owner, Vehicles>) root.fetch(Owner_.vehicles)
is necessary described in this 文章(请参阅 定义 JOIN FETCH 子句 部分).
我正在传递一组车辆名称,例如 ['car','jeep','truck','bike']
,并希望 select 使用条件查询在此列表中拥有 vehicles
的车主,这里的车主可以拥有多个 vahicles
(一对多)。我有一个限制,我需要使用 Criteria 查询。
class Owner {
@ID
@GeneratedValue(strategy = IDENTITY)
@Column(name = "owner_id")
private Long ownerId;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "owner_id")
private Set<Vehicles> vehicles;
}
class Vehicles {
@ID
@GeneratedValue(strategy = IDENTITY)
@Column(name = "vehicle_id")
private Long vehicleId;
@ManyToOne
@JoinColumn(name = "owner_id")
private Owner owner;
@Column(name="vehicle_name")
private String vehicleName;
}
以下是我尝试过但没有成功的方法
Criteria criteria = getSession().createCriteria(Owner.class);
criteria.createAlias("vehicles", "vehicles");
criteria.add(Restrictions.in("vehicles.vehicleName", setOfVehicles));
criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
首先,您的映射看起来不正确。 Owner
和 Vehicles
之间存在双向关联。因此,只有 @ManyToOne
侧应该用 @JoinColumn
注释。我将使用以下方式更正映射:
@Entity
@Table
public class Owner
{
@Id
@Column(name = "own_id")
private Long id;
@OneToMany(mappedBy = "owner")
private Set<Vehicles> vehicles;
}
@Entity
@Table
public class Vehicles
{
@Id
@Column(name = "veh_id")
private Long id;
@Column(name = "veh_name")
private String name;
@ManyToOne
@JoinColumn(name = "veh_own_id")
private Owner owner;
}
接下来我要强调的是,您尝试使用已弃用的 Hibernate org.hibernate.Criteria
API. I am going to provide an example for the Criteria API。因此,查询将具有以下视图:
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Owner> criteria = builder.createQuery(Owner.class);
Root<Owner> root = criteria.from(Owner.class);
SetJoin<Owner, Vehicles> vehs = (SetJoin<Owner, Vehicles>) root.fetch(Owner_.vehicles);
criteria
.select(root)
.distinct(true)
.where(
vehs.get(Vehicles_.NAME).in(Arrays.asList("car", "jeep", "truck", "bike"))
);
List<Owner> deps = session.createQuery(criteria).getResultList();
Owner_
和 Vehicles_
类 属于所谓的 JPA static metamodel. Why the casting (SetJoin<Owner, Vehicles>) root.fetch(Owner_.vehicles)
is necessary described in this 文章(请参阅 定义 JOIN FETCH 子句 部分).