#spring-data-jdbc
#spring-data-jdbc
Вопрос:
Возможна ли отложенная загрузка для Spring Data JDBC? Или проекция возможна?
Мне бы хотелось, чтобы в моих данных было только два поля, но, похоже, Spring JDBC извлекает все это целиком.
@Repository
public interface AppUserRepo extends CrudRepository<AppUser, Long> {
@Query("select id, firstname, lastname from m_appuser where firstname=:firstName")
public AppUser findByAppUserName(@Param("firstName") String firstName);
}
Это привело к получению всех связанных объектов.
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [SELECT "ROLE"."ID" AS "ID", "ROLE"."DEL" AS "DEL", "ROLE"."NAME" AS "NAME", "ROLE"."VERSION" AS "VERSION", "ROLE"."DISABLED" AS "DISABLED", "ROLE"."CREATED_DATE" AS "CREATED_DATE", "ROLE"."DESCRIPTION" AS "DESCRIPTION", "ROLE"."REFERENCE_NUMBER" AS "REFERENCE_NUMBER", "ROLE"."LAST_MODIFIED_DATE" AS "LAST_MODIFIED_DATE", "createdBy"."ID" AS "CREATEDBY_ID", "createdBy"."DEL" AS "CREATEDBY_DEL", "createdBy"."EMAIL" AS "CREATEDBY_EMAIL", "createdBy"."STATUS" AS "CREATEDBY_STATUS", "createdBy"."VERSION" AS "CREATEDBY_VERSION", "createdBy"."ENABLED" AS "CREATEDBY_ENABLED", "createdBy"."PASSWORD" AS "CREATEDBY_PASSWORD", "createdBy"."USER_TYPE" AS "CREATEDBY_USER_TYPE", "createdBy"."BRANCH_ID" AS "CREATEDBY_BRANCH_ID", "createdBy"."USERNAME" AS "CREATEDBY_USERNAME", "createdBy"."LASTNAME" AS "CREATEDBY_LASTNAME", "createdBy"."FIRSTNAME" AS "CREATEDBY_FIRSTNAME", "createdBy"."CLEAR_PSWD" AS "CREATEDBY_CLEAR_PSWD", "createdBy"."MIDDLENAME" AS "CREATEDBY_MIDDLENAME", "createdBy"."CREATED_DATE" AS "CREATEDBY_CREATED_DATE", "createdBy"."FAILED_LOGINS" AS "CREATEDBY_FAILED_LOGINS", "createdBy"."MOBILE_NUMBER" AS "CREATEDBY_MOBILE_NUMBER", "createdBy"."LAST_LOGIN_DATE" AS "CREATEDBY_LAST_LOGIN_DATE", "createdBy"."LAST_MODIFIED_DATE" AS "CREATEDBY_LAST_MODIFIED_DATE", "createdBy"."ACCOUNT_NON_LOCKED" AS "CREATEDBY_ACCOUNT_NON_LOCKED", "createdBy"."PROFILE_EXPIRY_DATE" AS "CREATEDBY_PROFILE_EXPIRY_DATE", "createdBy"."IS_SELF_SERVICE_USER" AS "CREATEDBY_IS_SELF_SERVICE_USER", "createdBy"."MOBILE_COUNTRY_CODE" AS "CREATEDBY_MOBILE_COUNTRY_CODE", "createdBy"."ACCOUNT_NON_EXPIRED" AS "CREATEDBY_ACCOUNT_NON_EXPIRED", "createdBy"."PASSWORD_NEVER_EXPIRES" AS "CREATEDBY_PASSWORD_NEVER_EXPIRES", "createdBy"."CREDENTIALS_NON_EXPIRED" AS "CREATEDBY_CREDENTIALS_NON_EXPIRED", "createdBy"."LAST_TIME_PASSWORD_UPDATED" AS "CREATEDBY_LAST_TIME_PASSWORD_UPDATED", "createdBy"."FIRST_TIME_LOGIN_REMAINING" AS "CREATEDBY_FIRST_TIME_LOGIN_REMAINING", "lastModifiedBy"."ID" AS "LASTMODIFIEDBY_ID", "lastModifiedBy"."DEL" AS "LASTMODIFIEDBY_DEL", "lastModifiedBy"."EMAIL" AS "LASTMODIFIEDBY_EMAIL", "lastModifiedBy"."STATUS" AS "LASTMODIFIEDBY_STATUS", "lastModifiedBy"."VERSION" AS "LASTMODIFIEDBY_VERSION", "lastModifiedBy"."ENABLED" AS "LASTMODIFIEDBY_ENABLED", "lastModifiedBy"."USERNAME" AS "LASTMODIFIEDBY_USERNAME", "lastModifiedBy"."BRANCH_ID" AS "LASTMODIFIEDBY_BRANCH_ID", "lastModifiedBy"."PASSWORD" AS "LASTMODIFIEDBY_PASSWORD", "lastModifiedBy"."LASTNAME" AS "LASTMODIFIEDBY_LASTNAME", "lastModifiedBy"."USER_TYPE" AS "LASTMODIFIEDBY_USER_TYPE", "lastModifiedBy"."CLEAR_PSWD" AS "LASTMODIFIEDBY_CLEAR_PSWD", "lastModifiedBy"."FIRSTNAME" AS "LASTMODIFIEDBY_FIRSTNAME", "lastModifiedBy"."MIDDLENAME" AS "LASTMODIFIEDBY_MIDDLENAME", "lastModifiedBy"."CREATED_DATE" AS "LASTMODIFIEDBY_CREATED_DATE", "lastModifiedBy"."FAILED_LOGINS" AS "LASTMODIFIEDBY_FAILED_LOGINS", "lastModifiedBy"."MOBILE_NUMBER" AS "LASTMODIFIEDBY_MOBILE_NUMBER", "lastModifiedBy"."LAST_LOGIN_DATE" AS "LASTMODIFIEDBY_LAST_LOGIN_DATE", "lastModifiedBy"."ACCOUNT_NON_LOCKED" AS "LASTMODIFIEDBY_ACCOUNT_NON_LOCKED", "lastModifiedBy"."LAST_MODIFIED_DATE" AS "LASTMODIFIEDBY_LAST_MODIFIED_DATE", "lastModifiedBy"."MOBILE_COUNTRY_CODE" AS "LASTMODIFIEDBY_MOBILE_COUNTRY_CODE", "lastModifiedBy"."PROFILE_EXPIRY_DATE" AS "LASTMODIFIEDBY_PROFILE_EXPIRY_DATE", "lastModifiedBy"."ACCOUNT_NON_EXPIRED" AS "LASTMODIFIEDBY_ACCOUNT_NON_EXPIRED", "lastModifiedBy"."IS_SELF_SERVICE_USER" AS "LASTMODIFIEDBY_IS_SELF_SERVICE_USER", "lastModifiedBy"."PASSWORD_NEVER_EXPIRES" AS "LASTMODIFIEDBY_PASSWORD_NEVER_EXPIRES", "lastModifiedBy"."CREDENTIALS_NON_EXPIRED" AS "LASTMODIFIEDBY_CREDENTIALS_NON_EXPIRED", "lastModifiedBy"."FIRST_TIME_LOGIN_REMAINING" AS "LASTMODIFIEDBY_FIRST_TIME_LOGIN_REMAINING", "lastModifiedBy"."LAST_TIME_PASSWORD_UPDATED" AS "LASTMODIFIEDBY_LAST_TIME_PASSWORD_UPDATED", "createdBy_staff"."ID" AS "CREATEDBY_STAFF_ID", "createdBy_staff"."ACTIVE" AS "CREATEDBY_STAFF_ACTIVE", "createdBy_staff"."MOBILE_NO" AS "CREATEDBY_STAFF_MOBILE_NO", "createdBy_staff"."LASTNAME" AS "CREATEDBY_STAFF_LASTNAME", "createdBy_staff"."FIRSTNAME" AS "CREATEDBY_STAFF_FIRSTNAME", "createdBy_staff"."EXTERNAL_ID" AS "CREATEDBY_STAFF_EXTERNAL_ID", "createdBy_staff"."LOAN_OFFICER" AS "CREATEDBY_STAFF_LOAN_OFFICER", "createdBy_staff"."DISPLAY_NAME" AS "CREATEDBY_STAFF_DISPLAY_NAME", "createdBy_staff"."JOINING_DATE" AS "CREATEDBY_STAFF_JOINING_DATE", "createdBy_staff"."EMAIL_ADDRESS" AS "CREATEDBY_STAFF_EMAIL_ADDRESS", "createdBy_staff"."ORGANISATIONAL_ROLE_TYPE" AS "CREATEDBY_STAFF_ORGANISATIONAL_ROLE_TYPE", "createdBy_office"."ID" AS "CREATEDBY_OFFICE_ID", "createdBy_office"."NAME" AS "CREATEDBY_OFFICE_NAME", "createdBy_office"."HIERARCHY" AS "CREATEDBY_OFFICE_HIERARCHY", "createdBy_office"."EXTERNAL_ID" AS "CREATEDBY_OFFICE_EXTERNAL_ID", "createdBy_office"."OPENING_DATE" AS "CREATEDBY_OFFICE_OPENING_DATE", "createdBy_tellerId"."ID" AS "CREATEDBY_TELLERID_ID", "createdBy_tellerId"."DEL" AS "CREATEDBY_TELLERID_DEL", "createdBy_tellerId"."NAME" AS "CREATEDBY_TELLERID_NAME", "createdBy_tellerId"."VERSION" AS "CREATEDBY_TELLERID_VERSION", "createdBy_tellerId"."TELLER_CODE" AS "CREATEDBY_TELLERID_TELLER_CODE", "createdBy_tellerId"."DESCRIPTION" AS "CREATEDBY_TELLERID_DESCRIPTION", "createdBy_tellerId"."CREATED_DATE" AS "CREATEDBY_TELLERID_CREATED_DATE", "createdBy_tellerId"."LAST_MODIFIED_DATE" AS "CREATEDBY_TELLERID_LAST_MODIFIED_DATE", "createdBy_departmentId"."ID" AS "CREATEDBY_DEPARTMENTID_ID", "createdBy_departmentId"."DEL" AS "CREATEDBY_DEPARTMENTID_DEL", "createdBy_departmentId"."VERSION" AS "CREATEDBY_DEPARTMENTID_VERSION", "createdBy_departmentId"."CREATED_DATE" AS "CREATEDBY_DEPARTMENTID_CREATED_DATE", "createdBy_departmentId"."DEPARTMENT_NAME" AS "CREATEDBY_DEPARTMENTID_DEPARTMENT_NAME", "createdBy_departmentId"."DEPARTMENT_CODE" AS "CREATEDBY_DEPARTMENTID_DEPARTMENT_CODE", "createdBy_departmentId"."REFERENCE_NUMBER" AS "CREATEDBY_DEPARTMENTID_REFERENCE_NUMBER", "createdBy_departmentId"."LAST_MODIFIED_DATE" AS "CREATEDBY_DEPARTMENTID_LAST_MODIFIED_DATE", "lastModifiedBy_staff"."ID" AS "LASTMODIFIEDBY_STAFF_ID", "lastModifiedBy_staff"."ACTIVE" AS "LASTMODIFIEDBY_STAFF_ACTIVE", "lastModifiedBy_staff"."MOBILE_NO" AS "LASTMODIFIEDBY_STAFF_MOBILE_NO", "lastModifiedBy_staff"."LASTNAME" AS "LASTMODIFIEDBY_STAFF_LASTNAME", "lastModifiedBy_staff"."FIRSTNAME" AS "LASTMODIFIEDBY_STAFF_FIRSTNAME", "lastModifiedBy_staff"."EXTERNAL_ID" AS "LASTMODIFIEDBY_STAFF_EXTERNAL_ID", "lastModifiedBy_staff"."DISPLAY_NAME" AS "LASTMODIFIEDBY_STAFF_DISPLAY_NAME", "lastModifiedBy_staff"."LOAN_OFFICER" AS "LASTMODIFIEDBY_STAFF_LOAN_OFFICER", "lastModifiedBy_staff"."JOINING_DATE" AS "LASTMODIFIEDBY_STAFF_JOINING_DATE", "lastModifiedBy_staff"."EMAIL_ADDRESS" AS "LASTMODIFIEDBY_STAFF_EMAIL_ADDRESS", "lastModifiedBy_staff"."ORGANISATIONAL_ROLE_TYPE" AS "LASTMODIFIEDBY_STAFF_ORGANISATIONAL_ROLE_TYPE", "lastModifiedBy_office"."ID" AS "LASTMODIFIEDBY_OFFICE_ID", "lastModifiedBy_office"."NAME" AS "LASTMODIFIEDBY_OFFICE_NAME", "lastModifiedBy_office"."HIERARCHY" AS "LASTMODIFIEDBY_OFFICE_HIERARCHY", "lastModifiedBy_office"."EXTERNAL_ID" AS "LASTMODIFIEDBY_OFFICE_EXTERNAL_ID", "lastModifiedBy_office"."OPENING_DATE" AS "LASTMODIFIEDBY_OFFICE_OPENING_DATE", "lastModifiedBy_tellerId"."ID" AS "LASTMODIFIEDBY_TELLERID_ID", "lastModifiedBy_tellerId"."DEL" AS "LASTMODIFIEDBY_TELLERID_DEL", "lastModifiedBy_tellerId"."NAME" AS "LASTMODIFIEDBY_TELLERID_NAME", "lastModifiedBy_tellerId"."VERSION" AS "LASTMODIFIEDBY_TELLERID_VERSION", "lastModifiedBy_tellerId"."TELLER_CODE" AS "LASTMODIFIEDBY_TELLERID_TELLER_CODE", "lastModifiedBy_tellerId"."CREATED_DATE" AS "LASTMODIFIEDBY_TELLERID_CREATED_DATE", "lastModifiedBy_tellerId"."DESCRIPTION" AS "LASTMODIFIEDBY_TELLERID_DESCRIPTION", "lastModifiedBy_tellerId"."LAST_MODIFIED_DATE" AS "LASTMODIFIEDBY_TELLERID_LAST_MODIFIED_DATE", "lastModifiedBy_departmentId"."ID" AS "LASTMODIFIEDBY_DEPARTMENTID_ID", "lastModifiedBy_departmentId"."DEL" AS "LASTMODIFIEDBY_DEPARTMENTID_DEL", "lastModifiedBy_departmentId"."VERSION" AS "LASTMODIFIEDBY_DEPARTMENTID_VERSION", "lastModifiedBy_departmentId"."CREATED_DATE" AS "LASTMODIFIEDBY_DEPARTMENTID_CREATED_DATE", "lastModifiedBy_departmentId"."DEPARTMENT_CODE" AS "LASTMODIFIEDBY_DEPARTMENTID_DEPARTMENT_CODE", "lastModifiedBy_departmentId"."DEPARTMENT_NAME" AS "LASTMODIFIEDBY_DEPARTMENTID_DEPARTMENT_NAME", "lastModifiedBy_departmentId"."REFERENCE_NUMBER" AS "LASTMODIFIEDBY_DEPARTMENTID_REFERENCE_NUMBER", "lastModifiedBy_departmentId"."LAST_MODIFIED_DATE" AS "LASTMODIFIEDBY_DEPARTMENTID_LAST_MODIFIED_DATE", "createdBy_staff_image"."ID" AS "CREATEDBY_STAFF_IMAGE_ID", "createdBy_staff_image"."LOCATION" AS "CREATEDBY_STAFF_IMAGE_LOCATION", "createdBy_staff_image"."STORAGE_TYPE" AS "CREATEDBY_STAFF_IMAGE_STORAGE_TYPE", "createdBy_staff_office"."ID" AS "CREATEDBY_STAFF_OFFICE_ID", "createdBy_staff_office"."NAME" AS "CREATEDBY_STAFF_OFFICE_NAME", "createdBy_staff_office"."HIERARCHY" AS "CREATEDBY_STAFF_OFFICE_HIERARCHY", "createdBy_staff_office"."EXTERNAL_ID" AS "CREATEDBY_STAFF_OFFICE_EXTERNAL_ID", "createdBy_staff_office"."OPENING_DATE" AS "CREATEDBY_STAFF_OFFICE_OPENING_DATE", "createdBy_departmentId_branch"."ID" AS "CREATEDBY_DEPARTMENTID_BRANCH_ID", "createdBy_departmentId_branch"."NAME" AS "CREATEDBY_DEPARTMENTID_BRANCH_NAME", "createdBy_departmentId_branch"."HIERARCHY" AS "CREATEDBY_DEPARTMENTID_BRANCH_HIERARCHY", "createdBy_departmentId_branch"."EXTERNAL_ID" AS "CREATEDBY_DEPARTMENTID_BRANCH_EXTERNAL_ID", "createdBy_departmentId_branch"."OPENING_DATE" AS "CREATEDBY_DEPARTMENTID_BRANCH_OPENING_DATE", "createdBy_departmentId_sourcePlaceCode"."ID" AS "CREATEDBY_DEPARTMENTID_SOURCEPLACECODE_ID", "createdBy_departmentId_sourcePlaceCode"."LABEL" AS "CREATEDBY_DEPARTMENTID_SOURCEPLACECODE_LABEL", "createdBy_departmentId_sourcePlaceCode"."POSITION" AS "CREATEDBY_DEPARTMENTID_SOURCEPLACECODE_POSITION", "createdBy_departmentId_sourcePlaceCode"."IS_ACTIVE" AS "CREATEDBY_DEPARTMENTID_SOURCEPLACECODE_IS_ACTIVE", "createdBy_departmentId_sourcePlaceCode"."MANDATORY" AS "CREATEDBY_DEPARTMENTID_SOURCEPLACECODE_MANDATORY", "createdBy_departmentId_sourcePlaceCode"."DESCRIPTION" AS "CREATEDBY_DEPARTMENTID_SOURCEPLACECODE_DESCRIPTION", "lastModifiedBy_staff_image"."ID" AS "LASTMODIFIEDBY_STAFF_IMAGE_ID", "lastModifiedBy_staff_image"."LOCATION" AS "LASTMODIFIEDBY_STAFF_IMAGE_LOCATION", "lastModifiedBy_staff_image"."STORAGE_TYPE" AS "LASTMODIFIEDBY_STAFF_IMAGE_STORAGE_TYPE", "lastModifiedBy_staff_office"."ID" AS "LASTMODIFIEDBY_STAFF_OFFICE_ID", "lastModifiedBy_staff_office"."NAME" AS "LASTMODIFIEDBY_STAFF_OFFICE_NAME", "lastModifiedBy_staff_office"."HIERARCHY" AS "LASTMODIFIEDBY_STAFF_OFFICE_HIERARCHY", "lastModifiedBy_staff_office"."EXTERNAL_ID" AS "LASTMODIFIEDBY_STAFF_OFFICE_EXTERNAL_ID", "lastModifiedBy_staff_office"."OPENING_DATE" AS "LASTMODIFIEDBY_STAFF_OFFICE_OPENING_DATE", "lastModifiedBy_departmentId_branch"."ID" AS "LASTMODIFIEDBY_DEPARTMENTID_BRANCH_ID", "lastModifiedBy_departmentId_branch"."NAME" AS "LASTMODIFIEDBY_DEPARTMENTID_BRANCH_NAME", "lastModifiedBy_departmentId_branch"."HIERARCHY" AS "LASTMODIFIEDBY_DEPARTMENTID_BRANCH_HIERARCHY", "lastModifiedBy_departmentId_branch"."EXTERNAL_ID" AS "LASTMODIFIEDBY_DEPARTMENTID_BRANCH_EXTERNAL_ID", "lastModifiedBy_departmentId_branch"."OPENING_DATE" AS "LASTMODIFIEDBY_DEPARTMENTID_BRANCH_OPENING_DATE", "lastModifiedBy_departmentId_sourcePlaceCode"."ID" AS "LASTMODIFIEDBY_DEPARTMENTID_SOURCEPLACECODE_ID", "lastModifiedBy_departmentId_sourcePlaceCode"."LABEL" AS "LASTMODIFIEDBY_DEPARTMENTID_SOURCEPLACECODE_LABEL", "lastModifiedBy_departmentId_sourcePlaceCode"."POSITION" AS "LASTMODIFIEDBY_DEPARTMENTID_SOURCEPLACECODE_POSITION", "lastModifiedBy_departmentId_sourcePlaceCode"."IS_ACTIVE" AS "LASTMODIFIEDBY_DEPARTMENTID_SOURCEPLACECODE_IS_ACTIVE", "lastModifiedBy_departmentId_sourcePlaceCode"."MANDATORY" AS "LASTMODIFIEDBY_DEPARTMENTID_SOURCEPLACECODE_MANDATORY", "lastModifiedBy_departmentId_sourcePlaceCode"."DESCRIPTION" AS "LASTMODIFIEDBY_DEPARTMENTID_SOURCEPLACECODE_DESCRIPTION", "createdBy_departmentId_sourcePlaceCode_code"."ID" AS "CREATEDBY_DEPARTMENTID_SOURCEPLACECODE_CODE_ID", "createdBy_departmentId_sourcePlaceCode_code"."NAME" AS "CREATEDBY_DEPARTMENTID_SOURCEPLACECODE_CODE_NAME", "createdBy_departmentId_sourcePlaceCode_code"."SYSTEM_DEFINED" AS "CREATEDBY_DEPARTMENTID_SOURCEPLACECODE_CODE_SYSTEM_DEFINED", "lastModifiedBy_departmentId_sourcePlaceCode_code"."ID" AS "LASTMODIFIEDBY_DEPARTMENTID_SOURCEPLACECODE_CODE_ID", "lastModifiedBy_departmentId_sourcePlaceCode_code"."NAME" AS "LASTMODIFIEDBY_DEPARTMENTID_SOURCEPLACECODE_CODE_NAME", "lastModifiedBy_departmentId_sourcePlaceCode_code"."SYSTEM_DEFINED" AS "LASTMODIFIEDBY_DEPARTMENTID_SOURCEPLACECODE_CODE_SYSTEM_DEFINED" FROM "ROLE" LEFT OUTER JOIN "APP_USER" AS "createdBy" ON "createdBy"."ROLE" = "ROLE"."ID" LEFT OUTER JOIN "APP_USER" AS "lastModifiedBy" ON "lastModifiedBy"."ROLE" = "ROLE"."ID" LEFT OUTER JOIN "STAFF" AS "createdBy_staff" ON "createdBy_staff"."APP_USER" = "createdBy"."ID" LEFT OUTER JOIN "OFFICE" AS "createdBy_office" ON "createdBy_office"."APP_USER" = "createdBy"."ID" LEFT OUTER JOIN "TELLER" AS "createdBy_tellerId" ON "createdBy_tellerId"."APP_USER" = "createdBy"."ID" LEFT OUTER JOIN "DEPARTMENT" AS "createdBy_departmentId" ON "createdBy_departmentId"."APP_USER" = "createdBy"."ID" LEFT OUTER JOIN "STAFF" AS "lastModifiedBy_staff" ON "lastModifiedBy_staff"."APP_USER" = "lastModifiedBy"."ID" LEFT OUTER JOIN "OFFICE" AS "lastModifiedBy_office" ON "lastModifiedBy_office"."APP_USER" = "lastModifiedBy"."ID" LEFT OUTER JOIN "TELLER" AS "lastModifiedBy_tellerId" ON "lastModifiedBy_tellerId"."APP_USER" = "lastModifiedBy"."ID" LEFT OUTER JOIN "DEPARTMENT" AS "lastModifiedBy_departmentId" ON "lastModifiedBy_departmentId"."APP_USER" = "lastModifiedBy"."ID" LEFT OUTER JOIN "IMAGE" AS "createdBy_staff_image" ON "createdBy_staff_image"."STAFF" = "createdBy_staff"."ID" LEFT OUTER JOIN "OFFICE" AS "createdBy_staff_office" ON "createdBy_staff_office"."STAFF" = "createdBy_staff"."ID" LEFT OUTER JOIN "OFFICE" AS "createdBy_departmentId_branch" ON "createdBy_departmentId_branch"."DEPARTMENT" = "createdBy_departmentId"."ID" LEFT OUTER JOIN "CODE_VALUE" AS "createdBy_departmentId_sourcePlaceCode" ON "createdBy_departmentId_sourcePlaceCode"."DEPARTMENT" = "createdBy_departmentId"."ID" LEFT OUTER JOIN "IMAGE" AS "lastModifiedBy_staff_image" ON "lastModifiedBy_staff_image"."STAFF" = "lastModifiedBy_staff"."ID" LEFT OUTER JOIN "OFFICE" AS "lastModifiedBy_staff_office" ON "lastModifiedBy_staff_office"."STAFF" = "lastModifiedBy_staff"."ID" LEFT OUTER JOIN "OFFICE" AS "lastModifiedBy_departmentId_branch" ON "lastModifiedBy_departmentId_branch"."DEPARTMENT" = "lastModifiedBy_departmentId"."ID" LEFT OUTER JOIN "CODE_VALUE" AS "lastModifiedBy_departmentId_sourcePlaceCode" ON "lastModifiedBy_departmentId_sourcePlaceCode"."DEPARTMENT" = "lastModifiedBy_departmentId"."ID" LEFT OUTER JOIN "CODE" AS "createdBy_departmentId_sourcePlaceCode_code" ON "createdBy_departmentId_sourcePlaceCode_code"."CODE_VALUE" = "createdBy_departmentId_sourcePlaceCode"."ID" LEFT OUTER JOIN "CODE" AS "lastModifiedBy_departmentId_sourcePlaceCode_code" ON "lastModifiedBy_departmentId_sourcePlaceCode_code"."CODE_VALUE" = "lastModifiedBy_departmentId_sourcePlaceCode"."ID" WHERE "ROLE"."APP_USER" = ?]; nested exception is com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-204, SQLSTATE=42704, SQLERRMC=DB2INST1.ROLE, DRIVER=4.21.29
Ответ №1:
Общие принципы.
В Spring Data JDBC нет концепции отложенной загрузки. Это, возможно, самое важное дизайнерское решение в Spring Data JDBC, и очень важно его понять:
Spring Data JDBC загрузит полный агрегат, включая все, на что ссылаются обычные ссылки Java. На вещи, которые не должны или не должны быть частью одного и того же агрегата, не должна ссылаться ссылка java, а только id. Для более подробного обсуждения этого см. Spring Data JDBC, ссылки и агрегаты.
Проекции, выполняемые другими модулями Spring Data, с использованием интерфейса в качестве возвращаемого значения, в настоящее время не поддерживаются, но вы можете использовать DTO, то есть выделенные классы, которые имеют подмножество свойств класса entity, в качестве возвращаемого значения.
Что происходит в вашем случае.
AppUser
кажется, есть ссылка на a Role
, которая загружается отдельным оператором select, что вы и видите. Этот выбор не контролируется запросом в аннотации. Вместо AppUser
этого экземпляр инициализируется результатом указанного запроса. Затем Spring Data JDBC отмечает, что существуют дополнительные ссылки, и разрешает их с помощью вышеупомянутых инструкций SQL.
Я понятия не имею, почему вы получаете исключение. Возможно, потому, что запрос слишком длинный?
Что вы должны сделать
Создайте новый класс AppUserProjection
, содержащий только поля в вашем запросе, и используйте его в качестве возвращаемого значения. Поскольку нет ссылки на Role
или других ссылок, никакие дополнительные SQL statments выполняться не будут.
Однако, что еще лучше и важнее, я думаю, что ваша доменная модель не подходит для использования с Spring Data JDBC. AppUser
и Role
, похоже, это два разных агрегата, и поэтому один ДОЛЖЕН ССЫЛАТЬСЯ НА ДРУГОЙ ПО ИДЕНТИФИКАТОРУ. Это приводит к немедленному удалению проекта отложенной загрузки. Для перехода от AppUser
одного к Role
другому вы используете идентификатор для загрузки Role
из отдельного RoleRepository
. Это даже позволяет вам реализовать любую стратегию кэширования, которую вы хотите.
Помимо ссылок вы можете заполнить объект из SQL-запроса, который не загружает все свойства. Все свойства, не отраженные в SQL, не будут установлены для объекта и, следовательно, будут иметь соответствующее значение по умолчанию. Однако это не рекомендуется, поскольку это создает неполные сущности, и любой код в вашем классе сущностей должен обрабатывать возможно отсутствующие значения, что усложняет код. Вместо этого используйте выделенные DTO, как описано выше.
Комментарии:
1. Привет, просто последующий комментарий по этому поводу, касающийся роли. Предполагается, что это сопоставление «многие к одному», которое мне трудно реализовать. Я попытался аннотировать AppUser общедоступного класса { @Column(«ROLE_ID») роль частной роли; } Сгенерированный оператор SQL не использует ROLE_ID, но вместо этого все еще использует идентификатор. Возможно ли много-к-одному в Spring JDBC?
2. Смотрите Ссылочную статью из ответа.