org.hibernate.QueryException: недопустимая попытка разыменования коллекции [events0_.id.typesOfEvents] со ссылкой на свойство элемента [type_id] - PullRequest
1 голос
/ 29 мая 2020

Я использую spring boot и jpa с успокаивающим api. когда я пытаюсь получить список событий, возникает этот тип ошибки - org.hibernate.QueryException: незаконная попытка разыменовать коллекцию [events0_.id.typesOfEvents] со ссылкой на свойство элемента [type_id]

Я передаю Перечислить объект в конструктор как аргументы в пользовательский запрос jpa, но этот запрос не будет выполнен, он вызовет ошибку.

Событие - это главный объект внутри этого объекта. Я взял список typeOfEvents с использованием отношения ManyToMany, и эти две таблицы идентификаторов сохранены в третьей таблице.

1.Event. java

@Builder
@ToString
@Entity
@Table(name = "events")
public @Data
class Events implements Comparable<Events> {

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

    @ManyToOne(cascade = CascadeType.REFRESH)
    @JoinColumn(name = "site_id")
    private Sites sites;

    @Column
    private boolean multipleDays;

    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "events_types",
            joinColumns = @JoinColumn(name = "e_id"),
            inverseJoinColumns = @JoinColumn(name = "t_id", unique = false))
    private List<TypesOfEvents> typesOfEvents = new ArrayList<TypesOfEvents>(Arrays.asList());

    @ManyToMany(cascade = CascadeType.DETACH)
    @JoinTable(name = "events_format",
            joinColumns = @JoinColumn(name = "e_id"),
            inverseJoinColumns = @JoinColumn(name = "fs_id", unique = false))
    private List<FormatStructure> formatStructure = new ArrayList<>();

    @Column
    private String startDate;

    @Column
    private String startTime;

    @Column
    private String endDate;

    @Column
    private String endTime;

    @Column
    private String eventName;

    @Column
    private String subTitle;

    @Column
    private String description;

    @Column
    private String location;

    @ManyToOne(cascade = CascadeType.REFRESH)
    @JoinColumn(name = "city_id")
    private City city;

    @ManyToOne(cascade = CascadeType.REFRESH)
    @JoinColumn(name = "venue_one_off_option_id")
    private VenueOneOffOptions venueOneOffOptions;

    @Column
    private double fee;

    @Column
    private boolean paid;

    @Column
    private String eventImg;

    @ManyToOne(cascade = CascadeType.REFRESH)
    @JoinColumn(name = "event_passport_option_id")
    private EventPassportOptions eventPassportOptions;

    @Column
    private int passportTickets;

    @Column
    private int remainingTickets;

    @Column
    private boolean passport;

    @Column
    private int passportDiscountPercent;

    @Column
    private String promoCode;

    @Column
    private String siteUrl;

    @Column
    private String ticketPurchaseSite;

    @Column
    private String videoUrl;


    @ManyToOne(cascade = CascadeType.REFRESH)
    @JoinColumn(name = "primary_contact_member_id")
    private Members primary_contact_member_id;


    @ManyToOne(cascade = CascadeType.REFRESH)
    @JoinColumn(name = "created_member_id")
    private Members created_member_id;

    @ManyToOne(cascade = CascadeType.REFRESH)
    @JoinColumn(name = "group_id")
    private Groups groups;

    @Column
    private String expectedAttendance;

    @Column
    private boolean myFavourite;

    @ManyToOne(cascade = CascadeType.REFRESH)
    @JoinColumn(name = "eventStatusId")
    private EventStatus eventStatus;

    @Column
    private boolean purchasedPromotionalEmails;

    @Column
    private boolean featured;

    @ManyToMany(cascade = CascadeType.DETACH)
    @JoinTable(name = "events_audience_types",
            joinColumns = @JoinColumn(name = "e_id"),
            inverseJoinColumns = @JoinColumn(name = "at_id", unique = false))
    private List<AudienceTypes> audienceTypes = new ArrayList<>();

    @ManyToMany(cascade = CascadeType.DETACH)
    @JoinTable(name = "events_food_options",
            joinColumns = @JoinColumn(name = "e_id"),
            inverseJoinColumns = @JoinColumn(name = "fo_id", unique = false))
    private List<FoodOptions> foodOptions = new ArrayList<>();

    public Events() {
    }


    @Override
    public int compareTo(Events o) {
        return (int) (this.id - o.id);
    }
}

2.EventDTO. java

@ToString
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.CUSTOM)
public @Data
class TestDTO implements Comparable<TestDTO>{

    private Long id;

    private boolean multipleDays;

    private List<TypesOfEvents> eventType = new ArrayList<>(Arrays.asList());

    private String startDate;

    private String startTime;

    private String endDate;

    private String endTime;

    private String eventName;

    private String subTitle;

    private String location;

    private String city;

    private double fee;

    private boolean paid;

    private String eventImg;

    private Long passportOption;

    private int passportTickets;

    private int remainingTickets;

    private boolean passport;

    private String promoCode;

    private String expectedAttendance;

    private boolean myFavourite;

    private String eventStatus;

    private boolean featured;

    public TestDTO(Long id, boolean multipleDays, List<TypesOfEvents> eventType, String startDate, String startTime, String endDate, String endTime, String eventName, String subTitle, String location, String city, double fee, boolean paid, String eventImg, Long passportOption, int passportTickets, int remainingTickets, boolean passport, String promoCode, String expectedAttendance, boolean myFavourite, String eventStatus, boolean featured) {
        this.id = id;
        this.multipleDays = multipleDays;
        this.eventType = eventType;
        this.startDate = startDate;
        this.startTime = startTime;
        this.endDate = endDate;
        this.endTime = endTime;
        this.eventName = eventName;
        this.subTitle = subTitle;
        this.location = location;
        this.city = city;
        this.fee = fee;
        this.paid = paid;
        this.eventImg = eventImg;
        this.passportOption = passportOption;
        this.passportTickets = passportTickets;
        this.remainingTickets = remainingTickets;
        this.passport = passport;
        this.promoCode = promoCode;
        this.expectedAttendance = expectedAttendance;
        this.myFavourite = myFavourite;
        this.eventStatus = eventStatus;
        this.featured = featured;
    }
}   

3.Query

@Query("SELECT new com.test.responseDTO.TestDTO(e.id, e.multipleDays, e.typesOfEvents, e.startDate, e.startTime, e.endDate, e.endTime, e.eventName, e.subTitle, e.location, c.name, e.fee, e.paid, e.eventImg, p.event_passport_option_id, e.passportTickets, e.remainingTickets, e.passport, e.promoCode, e.expectedAttendance, e.myFavourite, s.status, e.featured)" +
            " from Events e LEFT JOIN e.typesOfEvents.type_id t JOIN e.city c JOIN e.eventPassportOptions p JOIN e.eventStatus s WHERE e.startDate BETWEEN :startDate AND :endDate AND e.endDate BETWEEN :startDate AND :endDate ORDER BY e.startDate, e.id ASC")
    List<TestDTO> findAllListOfEventsWithoutEventTypeIdWithOnlyTwoDateTest1(String startDate, String endDate);

4.Ошибка

org.hibernate.QueryException: illegal attempt to dereference collection [events0_.id.typesOfEvents] with element property reference [type_id]

1 Ответ

0 голосов
/ 29 мая 2020

Вы ссылаетесь на type_id из списка, который здесь не разрешен, потому что выражение запроса ссылается на type_id на список, а не на сам объект. Так что замените только это LEFT JOIN e.typesOfEvents.type_id t на LEFT JOIN e.typesOfEvents t, и все будет нормально. И он будет ссылаться на переменную t на элемент из списка (Relation).

    @Query("SELECT new com.test.responseDTO.TestDTO(e.id, e.multipleDays, e.typesOfEvents, e.startDate, e.startTime, e.endDate, e.endTime, e.eventName, e.subTitle, e.location, c.name, e.fee, e.paid, e.eventImg, p.event_passport_option_id, e.passportTickets, e.remainingTickets, e.passport, e.promoCode, e.expectedAttendance, e.myFavourite, s.status, e.featured)" +
            " from Events e LEFT JOIN e.typesOfEvents t /*this fixed*/ JOIN e.city c JOIN e.eventPassportOptions p JOIN e.eventStatus s WHERE e.startDate BETWEEN :startDate AND :endDate AND e.endDate BETWEEN :startDate AND :endDate ORDER BY e.startDate, e.id ASC")
    List<TestDTO> findAllListOfEventsWithoutEventTypeIdWithOnlyTwoDateTest1(String startDate, String endDate);

My Query с изменениями в TestDTO

    @Query("SELECT new com.techavidus.networkingPhoniex.responseDTO.TestDTO(e.id, e.multipleDays, t, e.startDate, e.startTime, e.endDate, e.endTime, e.eventName, e.subTitle, e.location, c.name, e.fee, e.paid, e.eventImg, p.event_passport_option_id, e.passportTickets, e.remainingTickets, e.passport, e.promoCode, e.expectedAttendance, e.myFavourite, s.status, e.featured)" +
            " from Events e LEFT JOIN e.typesOfEvents t JOIN e.city c JOIN e.eventPassportOptions p JOIN e.eventStatus s WHERE e.startDate BETWEEN :startDate AND :endDate AND e.endDate BETWEEN :startDate AND :endDate ORDER BY e.startDate, e.id ASC")
    List<TestDTO> findAllListOfEventsWithoutEventTypeIdWithOnlyTwoDateTest1(String startDate, String endDate);

вывод:

{
  "success": true,
  "message": "Record's find successfully.",
  "data": [
    {
      "date": "2020/05/28",
      "count": 2,
      "events": [
        {
          "id": 1,
          "multipleDays": true,
          "eventType": {
            "type_id": 1,
            "type": "Musician1",
            "paid_listing": false,
            "color": "Black",
            "_enabled": true
          },
          "startDate": "2020/05/28",
          "startTime": "10:12:15",
          "endDate": "2020/05/30",
          "endTime": "20:18:25",
          "eventName": "Test",
          "subTitle": "Testing demo",
          "location": "string",
          "city": "Bhuj",
          "fee": 49,
          "paid": false,
          "eventImg": "Imgage url",
          "passportOption": 1,
          "passportTickets": 0,
          "remainingTickets": 0,
          "passport": false,
          "promoCode": "TEST123",
          "expectedAttendance": "1500",
          "myFavourite": false,
          "eventStatus": "Pending Approval",
          "featured": false
        },
        {
          "id": 1,
          "multipleDays": true,
          "eventType": {
            "type_id": 2,
            "type": "Personal Growth",
            "paid_listing": true,
            "color": "Black",
            "_enabled": true
          },
          "startDate": "2020/05/28",
          "startTime": "10:12:15",
          "endDate": "2020/05/30",
          "endTime": "20:18:25",
          "eventName": "Test",
          "subTitle": "Testing demo",
          "location": "string",
          "city": "Bhuj",
          "fee": 49,
          "paid": false,
          "eventImg": "Imgage url",
          "passportOption": 1,
          "passportTickets": 0,
          "remainingTickets": 0,
          "passport": false,
          "promoCode": "TEST123",
          "expectedAttendance": "1500",
          "myFavourite": false,
          "eventStatus": "Pending Approval",
          "featured": false
        }
      ]
    }
  ]
}

...