Критерии гибернации для извлечения записей из отношений OneToMany - PullRequest
1 голос
/ 19 марта 2020

Я передаю коллекцию имен транспортных средств, таких как ['car','jeep','truck','bike'], и хочу выбрать владельцев, которым принадлежит vehicles, в этом списке с помощью запроса Criteria. Владелец может иметь несколько vahicles (OneToMany). У меня есть ограничение на использование запроса 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);

1 Ответ

1 голос
/ 22 марта 2020

Прежде всего, ваше отображение выглядит некорректно. У вас двунаправленная связь между 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 . Я собираюсь привести пример для 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 stati c метамодели . Почему приведение (SetJoin<Owner, Vehicles>) root.fetch(Owner_.vehicles) необходимо, описано в этой статье (см. Определение раздела JOIN FETCH раздел).

...