EclipseLink 2.7.3 вызывает исключение QueryException (точно так же, как ошибка 493235)

#java #eclipselink #multi-tenant

#java #eclipselink #многопользовательский

Вопрос:

У меня есть система, использующая мультитенантность с Schema дискриминатором, использующая EclipseLink 2.7.3. Я перешел на EclipseLink 2.7.3 именно для того, чтобы избежать этой (ошибки 493235) (и других) ошибок. Однако я получаю следующее исключение:

 java.lang.IllegalArgumentException: Exception [EclipseLink-6069] (Eclipse Persistence Services - 2.7.3.v20180807-4be1041): org.eclipse.persistence.exceptions.QueryException
Exception Description: The field [`database_1`.library.libId] in this expression has an invalid table in this context.
Query: ReadAllQuery(name="Library.findByReservationId" referenceClass=Library jpql="SELECT l FROM Library l WHERE l.libId = (SELECT r.lib.libId FROM Reservation r WHERE r.reservId = :reservId)")
  

Мои объекты выглядят так:

 @Entity
@Multitenant(value = TABLE_PER_TENANT)
@TenantTableDiscriminator(type = SCHEMA, contextProperty = MULTITENANT_PROPERTY_DEFAULT)
@Table(name = "library")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Library.findByReservId", query = "SELECT l FROM Library l WHERE l.libId = (SELECT r.lib.libId FROM Reservation r WHERE r.reservId = :reservId)")})
public class Library implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "libId")
    private Long libId;
    ...
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "libId")
    private List<Reservation> reservList;
    ...
}

@Entity
@Multitenant(value = TABLE_PER_TENANT)
@TenantTableDiscriminator(type = SCHEMA, contextProperty = MULTITENANT_PROPERTY_DEFAULT)
@Table(name = "reservation")
@XmlRootElement
public class Reservation implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "reservId")
    private Long reservId;
    @JoinColumn(name = "lib", referencedColumnName = "libId")
    @ManyToOne(optional = false)
    private Library lib;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "reservation")
    private List<BookReservation> bookReservationList;
    @Transient
    private List<Long> bookIdList;
    ...
}
  

Предполагается, что эта ошибка исчезла с версией 2.7. Я ошибаюсь? Может ли здесь быть что-то еще? Эта ошибка также преследует EclipseLink 2.7.3?
Спасибо за ваши ответы.

Комментарии:

1. Первое, что я бы сделал, это попробовать это без многопользовательской аренды, чтобы посмотреть, работает ли запрос или нет. Трудно сказать, связано ли это с 493235 или с чем-то еще в вашем коде. Однако, глядя на класс резервирования, он имеет ссылку libId на Library; ваш запрос пытается использовать r.lib.libId, когда он, вероятно, должен использовать r.libId.libId для работы.

2. Крис, спасибо тебе за твое острое зрение. Имена в моем исходном коде разные, поэтому, боюсь, я забыл изменить libId в резервировании на lib (теперь отредактировано). Таким образом, с запросом нет реальной проблемы, просто моя небрежность. Я должен сказать, что запрос работает нормально. Исключение выдается только спорадически, без конкретной причины. Может быть, когда многие вызовы служб происходят почти одновременно? На данный момент я не уверен.

3. Ошибка, на которую вы ссылаетесь, не была исправлена — она просто включала исправление, которое не было объединено с базой кода. В проекте, для которого я использовал это, я отказался от использования именованных запросов, чтобы избежать этой же проблемы. Поскольку с параметрами MT именованные запросы повторно анализируются при получении каждого EntityManager, для нас в любом случае не было экономии при использовании именованных запросов. Мы переключились на использование EntityManagerFactory для каждого клиента, а затем просто использовали обычные параметры сохранения JPA в конце, что дало нам больше контроля над клиентами и тем, что кэшируется для каждого в виртуальной машине.

4. «Ошибка, на которую вы ссылаетесь, не была исправлена» Что??? Вау… Спасибо, Крис. Я бы никогда не подумал об этом. Я имею в виду, это была ошибка, было исправление … почему бы не включить его в следующую основную версию?? В любом случае, спасибо и спасибо за совет о NamedQueries. Переписывать все эти запросы — настоящий облом, но я думаю, мне, вероятно, придется это сделать.

5. Это проблема с открытым исходным кодом — любой может отправлять ошибки и исправления, но коммиттеру все равно требуется некоторое время, чтобы получить мотивацию для его работы; создавать и запускать тесты, получать одобрение слияния и т.д. Я нашел обходной путь болезненным и переключился обратно на именованные запросы, поэтому я мог бы попробовать исправление поверх наших двоичных файлов в какой-то момент, если мы вернемся к использованию одного EMF. Это может быть для вас вариантом; попробуйте протестировать исправление, прежде чем переписывать что-либо