2016-05-31 61 views
0

你好我想執行原生SQL查詢,但得到的例外如下PSQLException:錯誤:語法錯誤或接近「表名」位置:1

查詢我試圖執行的是如下:

public List<Category> getAllCategories(){ 
    List<Category> categories = getEntityManager().createNativeQuery("Category.getAllAfterMerge", Category.class).getResultList(); 
    return categories; 
} 

和NamedNative查詢是如下

@NamedNativeQuery(name="Category.getAllAfterMerge", query="SELECT C.ID, C.CODE, COALESCE(R.DISPLAY_NAME, C.NAME) as NAME, C.PARENT_ID, C.PATH, C.COMP_ID, C.CREATED_ON, C.MODIFIED_ON FROM CATEGORY C LEFT JOIN REFERENCE_VALUES R ON C.ID = R.REFERENCE_VALUE_CODE AND R.REFERENCE_OBJ_NAME = 'CATEGORY';") 

表是如下

CREATE TABLE category 
(
    id bigserial NOT NULL PRIMARY KEY, 
    code text NOT NULL, 
    name text NOT NULL, 
    parent_id bigint, 
    path text, 
    comp_id bigint, 
    created_on timestamp without time zone, 
    modified_on timestamp without time zone, 
) 

而且Reference_Values表如下

CREATE TABLE reference_values 
(
    id serial NOT NULL PRIMARY KEY, 
    reference_obj_name text, 
    reference_value_code bigint, 
    display_name text, 
    created_on timestamp without time zone, 
    modified_on timestamp without time zone, 
) 

的實體是如下Category.java

@Entity 
@Table(name = "category") 
@NamedNativeQuery(name="Category.getAllAfterMerge", query="SELECT C.ID, C.CODE, COALESCE(R.DISPLAY_NAME, C.NAME) as NAME, C.PARENT_ID, C.PATH, C.COMP_ID, C.CREATED_ON, C.MODIFIED_ON FROM CATEGORY C LEFT JOIN REFERENCE_VALUES R ON C.ID = R.REFERENCE_VALUE_CODE AND R.REFERENCE_OBJ_NAME = 'CATEGORY';") 
public class Category extends Persistent { 

private static final long serialVersionUID = 1L; 

@ManyToOne 
private Category parent; 

@OneToMany(mappedBy = "parent") 
private Set<Category> children; 

private String code; 

private String name; 

private String path; 

@Column(name = "comp_id") 
private Integer compId; 

而且ReferenceValues.java如下

@Entity 
@Table(name = "reference_values") 
@NamedQuery(name = "ReferenceValues.findAll", query = "SELECT r FROM ReferenceValues r") 
public class ReferenceValues extends Persistent implements Serializable { 
private static final long serialVersionUID = 1L; 

@Column(name = "display_name") 
private String displayName; 

@Column(name = "reference_obj_name") 
private String referenceObjName; 

@Column(name = "reference_value_code") 
private Long referenceValueCode; 

例外是如下:

javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet 
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692) 
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602) 
at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:492) 
at getAllCategories(JpaCategoryDAO.java:18) 
at CategoryServiceImplTest.testGetAllCategories(CategoryServiceImplTest.java:29) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) 
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) 
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) 
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193) 
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:670) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet 
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106) 
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) 
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111) 
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97) 
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:79) 
at org.hibernate.loader.Loader.getResultSet(Loader.java:2115) 
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1898) 
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1874) 
at org.hibernate.loader.Loader.doQuery(Loader.java:919) 
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336) 
at org.hibernate.loader.Loader.doList(Loader.java:2610) 
at org.hibernate.loader.Loader.doList(Loader.java:2593) 
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2422) 
at org.hibernate.loader.Loader.list(Loader.java:2417) 
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:336) 
at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:1980) 
at org.hibernate.internal.AbstractSessionImpl.list(AbstractSessionImpl.java:322) 
at org.hibernate.internal.SQLQueryImpl.list(SQLQueryImpl.java:125) 
at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:606) 
at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:483) 
... 31 more 
Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "Category" 
    Position: 1 
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2284) 
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2003) 
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:200) 
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:424) 
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:161) 
at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:114) 
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70) 
... 46 more 
+0

這是否運行的查詢,而不您的本地Postgres數據庫中存在問題? –

+0

@TimBiegeleisen是查詢在postgres中運行。 – praveen

+0

您可以啓用hibernate.show_sql標誌並查看實際正在執行的hibernate。 –

回答

1

您需要使用createNamedQuery()方法的命名查詢,並添加resultClass@NamedNativeQuery

List<Category> categories = getEntityManager() 
    .createNamedQuery("Category.getAllAfterMerge").getResultList(); 

@NamedNativeQuery(name = "Category.getAllAfterMerge", 
    query = "SELECT C.ID, C.CODE, COALESCE(R.DISPLAY_NAME, C.NAME) as NAME, 
    C.PARENT_ID, C.PATH, C.COMP_ID, C.CREATED_ON, C.MODIFIED_ON 
    FROM CATEGORY C LEFT JOIN REFERENCE_VALUES R ON C.ID = 
    R.REFERENCE_VALUE_CODE AND R.REFERENCE_OBJ_NAME = 'CATEGORY'", 
    resultClass = Category.class) 

也許,你需要使用引號的別名

COALESCE(R.DISPLAY_NAME, C.NAME) as \"NAME\"

+0

加入resultClass = Category.class解決了這個問題。 – praveen

+1

@praveen我很高興。感謝您接受答案。 :) –

相關問題