我正在尝试将原生@Query与Spring Data存储库类一起使用。我正在使用Microsoft SQL Server JDBC驱动程序。但是,我在执行中遇到了问题。我有一个名为" TicketSystem"在数据库中。此架构中的表使用CamelCase。但是,每当我执行此操作时:
public interface TicketRepository extends CrudRepository<Ticket, Integer> {
@Query(value = "SELECT * FROM TicketSystem.Ticket WHERE IsOpen = 1"
+ "AND PropertyID IN ( SELECT PropertyID from OAuth.user_properties WHERE authid = ?1)"
+ "AND ItemID in ( SELECT ID from [TicketSystem].[TicketItem] WHERE ItemCatID IN "
+ "(SELECT ItemCatID FROM TicketSystem.Roles_ItemCategories WHERE RoleID IN "
+ "(SELECT role_id from OAuth.user_role WHERE user_id = ?1)))", nativeQuery = true)
List<Ticket> findOpenTicketsByUser(Integer userID);
}
好像是用_代替大写字母。
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 'ticket_item'.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:258) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1535) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:467) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:409) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7151) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2478) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:219) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:199) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(SQLServerPreparedStatement.java:331) ~[mssql-jdbc-6.2.2.jre8.jar:na]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52) ~[HikariCP-2.7.8.jar:na]
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java) ~[HikariCP-2.7.8.jar:na]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:60) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
... 86 common frames omitted
从某种意义上说,这是正确的。数据库中没有ticket_item对象(它是TicketItem)。但是,我试图弄清楚它为什么要执行转换。该查询确实引用了另一个使用下划线的模式(OAuth)(以便与Spring Security OAuth2集成);我不确定这是否是一个促成因素。
我理解Hibernate和Spring Data允许各种命名策略虽然我最初并不认为这会影响原生查询,但我尝试将策略切换为spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
结果略有不同2018-04-03 08:39:31.665 ERROR 12356 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : Invalid object name 'TicketItem'.
。
但是,TicketItem确实存在。
无论有没有[],我都试过了。如果我没有限定对象名称(使用TicketSystem);应用程序甚至找不到第一个对象(Ticket)。
@Query派生自一个工作存储过程(我没有使用@NamedStoredProcedure,因为我无法确定如何使用该机制检索Entity类的集合)。
/****** Object: StoredProcedure [TicketSystem].[FindOpenTicketsByUser] Script Date: 4/3/2018 8:42:58 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [TicketSystem].[FindOpenTicketsByUser]
@UserID INT
AS
SELECT * FROM TicketSystem.Ticket WHERE IsOpen = 1
AND PropertyID IN ( SELECT PropertyID from OAuth.user_properties WHERE authid = @UserID)
AND ItemID in ( SELECT ID from TicketSystem.TicketItem WHERE ItemCatID IN
(SELECT ItemCatID FROM TicketSystem.Roles_ItemCategories WHERE RoleID IN
(SELECT role_id from OAuth.user_role WHERE user_id = @UserID)
));
我正在使用Spring Boot 2和相关的spring-boot-starter-data-jpa
。
感谢您的帮助。