#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. Это может быть для вас вариантом; попробуйте протестировать исправление, прежде чем переписывать что-либо