问题
I am passing a collection of vehicles names like ['car','jeep','truck','bike']
and want to select those owners who owns vehicles
in this list using Criteria query, Owner here can own multiple vahicles
(OneToMany). I have a limitation that i need to use Criteria query.
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;
}
Below is what i have tried but no success
Criteria criteria = getSession().createCriteria(Owner.class);
criteria.createAlias("vehicles", "vehicles");
criteria.add(Restrictions.in("vehicles.vehicleName", setOfVehicles));
criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
回答1:
First of all, your mapping looks incorrect. You have a bidirectional association between Owner
and Vehicles
. So, only the @ManyToOne
side should be annotated by @JoinColumn
. I will use the corrected in the following way mapping:
@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;
}
Next thing that I have to emphasize, you try to use deprecated Hibernate org.hibernate.Criteria
API. I am going to provide an example for the Criteria API. So, the query will have the following view:
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();
The Owner_
and Vehicles_
classes belong to so called JPA static metamodel. Why the casting (SetJoin<Owner, Vehicles>) root.fetch(Owner_.vehicles)
is necessary described in this article (see Defining a JOIN FETCH clause section).
来源:https://stackoverflow.com/questions/60761196/hibernate-criteria-to-pull-records-from-onetomany-relations