QueryException при использовании Spring Data Rest с EclipseLink в мультитенантной системе - PullRequest
0 голосов
/ 13 февраля 2019

Я использую Spring data rest и EclipseLink для создания мультитенантного приложения с одной таблицей.

Но я не могу создать репозиторий, в котором я могу вызывать пользовательские параметры QueryParameters.

Мой класс Kid.

@Entity
@Table(name="kid")
@Multitenant
public class Kid {

   @Id
   private Long id;

   @Column(name = "tenant_id")
   private String tenant_id;

   @Column(name = "mother_id")
   private Long motherId;

   //more attributes, constructor, getter and setter
}

Мой KidRepository

@RepositoryRestResource
public interface KidRepository extends PagingAndSortingRepository<Kid, Long>, QuerydslPredicateExecutor<Kid> {}

Когда я вызываю localhost / kids, я получаю следующее исключение:

Exception [EclipseLink-6174] (Eclipse Persistence Services - 2.7.4.v20190115-ad5b7c6b2a): 
org.eclipse.persistence.exceptions.QueryException\r\nException Description: No value was provided for the session property [eclipselink.tenant-id]. 
This exception is possible when using additional criteria or tenant discriminator columns without specifying the associated contextual property. 
These properties must be set through EntityManager, EntityManagerFactory or persistence unit properties. 
If using native EclipseLink, these properties should be set directly on the session.

Когда я удаляю аннотацию @Multitenant на моем объекте, все работает нормально.Так что он определенно имеет отношение к EclipseLink.

Когда я не расширяю QuerydslPredicateExecutor, он тоже работает.Но тогда я должен сам реализовать все findBy *.И даже при этом он снова ломается.Изменение моего репозитория KidsRepository на:

@RepositoryRestResource
public interface KidRepository extends PagingAndSortingRepository<Kid, Long> {
    Collection<Kid> findByMotherId(@Param("motherId") Long motherId);
}

Когда я сейчас вызываю localhost / kids / search / findByMotherId? MotherId = 1, я получаю то же исключение, что и выше.

Я использовал это руководство для настройкиEcpliseLink с JPA: https://blog.marcnuri.com/spring-data-jpa-eclipselink-configuring-spring-boot-to-use-eclipselink-as-the-jpa-provider/, означает, что PlatformTransactionManager, createJpaVendorAdapter и getVendorProperties перезаписываются.Идентификатор tenant-идентификатора поставляется с jwt, и все работает нормально, пока я не использую QuerydslPredicateExecutor, что является обязательным для варианта использования.

Оказывается, что используется неправильный JpaTransactionManager, мы полагаемся на QuerydslPredicateExecutor.Я не мог выяснить, какой из них создан, но, имея несколько точек останова в коде EclipseLink Framework, ни одна из них не была поражена.Это верно как для использования QuerydslPredicateExecutor, так и для пользовательского метода findby.

Я много гуглил и пытался переопределить некоторые из основных методов EclipseLink, но ни один из них не сработал.У меня заканчиваются варианты.

У кого-нибудь есть идеи, как это исправить или обойти это?

1 Ответ

0 голосов
/ 22 февраля 2019

Я смог обойти эту ошибку, реализовав собственные методы findBy * с использованием JPAQuery и QueryDsl:

@Repository
public class MyDao {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public Kid findByMotherId(Long motherId) {
        final JPAQuery<Kid> query = new JPAQuery<>(this.entityManager);
        final QKid kid = QKid.kid;

        return  query.from(kid)
            .where(kid.motherId.eq(motherId))
            .fetchOne();
    }
}

Это означает, что я должен написать весь свой запрос самостоятельно.Но многопользовательская работа работает.

...