5

我正在使用 JPA 和 Hibernate 和 Postgresql 开发一个应用程序。使用 Netbeans 向导,我从现有数据库创建了实体类。此类之一的摘录如下:

@Entity
@Table(name = "ADM_TYPES")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "AdmTypes.findAll", query = "SELECT a FROM AdmTypes a"),
    @NamedQuery(name = "AdmTypes.findByCType", query = "SELECT a FROM AdmTypes a WHERE a.cType = :cType"),
    @NamedQuery(name = "AdmTypes.findByVlType", query = "SELECT a FROM AdmTypes a WHERE a.vlType = :vlType"),
    @NamedQuery(name = "AdmTypes.findByDsType", query = "SELECT a FROM AdmTypes a WHERE a.dsType = :dsType"),
    @NamedQuery(name = "AdmTypes.findByVlStatus", query = "SELECT a FROM AdmTypes a WHERE a.vlStatus = :vlStatus"),
    @NamedQuery(name = "AdmTypes.findByCTypePrefix", query = "SELECT a FROM AdmTypes a WHERE a.cType like :cTypePrefix")})
public class AdmTypes implements Serializable {

在 EJB 中,我有:

@Stateless 
@LocalBean
public class ModelManagement {
    @PersistenceContext 
    private EntityManager em;

    public List<AdmTypes> listAdmTypesPrefix(String prefix){
        TypedQuery<AdmTypes> query = em.createNamedQuery("AdmTypes.findByCTypePrefix", AdmTypes.class);
        query.setParameter("cTypePrefix", "'%"+prefix+"%'");
        return query.getResultList();
    }

当我尝试执行ModelManagement.listAdmTypesPrefix("APREFIX")它会产生以下错误:

javax.ejb.EJBException
    at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:5193)
    at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5091)
    at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4879)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2039)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1990)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
    at $Proxy192.listAdmTypesPrefix(Unknown Source)
    at com.librethinking.simmodsys.ejb.__EJB31_Generated__ModelManagement__Intf____Bean__.listAdmTypesPrefix(Unknown Source)
    at com.librethinking.MockServlet.processRequest(MockServlet.java:64)
    at com.librethinking.MockServlet.doGet(MockServlet.java:94)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:722)
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: ERROR: relation "adm_types" does not exist
  Position: 136
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1367)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1295)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:265)
    at com.librethinking.simmodsys.ejb.ModelManagement.listAdmTypesPrefix(ModelManagement.java:39)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
    at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
    at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5366)
    at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
    at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370)
    at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5338)
    at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5326)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214)
    ... 32 more
Caused by: org.hibernate.exception.SQLGrammarException: ERROR: relation "adm_types" does not exist
  Position: 136
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:122)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
    at $Proxy194.executeQuery(Unknown Source)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:1953)
    at org.hibernate.loader.Loader.doQuery(Loader.java:829)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:289)
    at org.hibernate.loader.Loader.doList(Loader.java:2438)
    at org.hibernate.loader.Loader.doList(Loader.java:2424)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2254)
    at org.hibernate.loader.Loader.list(Loader.java:2249)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:470)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355)
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1248)
    at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:256)
    ... 55 more
Caused by: org.postgresql.util.PSQLException: ERROR: relation "adm_types" does not exist
  Position: 136
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2101)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1834)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:510)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:386)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:271)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
    ... 70 more

我知道 Postgres 对大写的表名有点烦人,但是如何将查询更改为指向“ADM_TYPES”而不是 AdmTypes?这不应该自动完成吗(毕竟我从现有数据库创建了实体类)?代码有什么问题?

谢谢!

4

1 回答 1

10

Postgres (used to, not sure on the newer) convert table names to lower case. That's the preferred operating procedure. If you log your queries you'll see hibernate may be or may not be quoting your table name (I'd guess it isn't).

Hibernate saving User model to Postgres

Honestly, if you're running on Postgres you really should either configure hibernate properly, or, as I would look at it, normalize your database as tables shouldn't have a namespace collision (thus removing the problem).

//From the article...

@Entity
@Table(name="\"User\"")
public class User {
    ...
}

EDITED 07/31/12:

This change must be done to the fields of the tables in the following way:

For @Column, change the name of the column adding escaped ":

@Column(name = "\"C_MODEL\"") 

For @JoinColumn, change the name of the column adding `:

@JoinColumn(name = "`TP_MODEL`")

You will have to do it manually on the columns giving you errors.

于 2012-07-21T20:36:34.577 回答