【问题标题】:JPA access Postgresql 9.4 generated sequence "id" not exist errorJPA 访问 Postgresql 9.4 生成的序列“id”不存在错误
【发布时间】:2015-05-08 07:46:51
【问题描述】:

我有一个项目需要设置适用于 JAVA-EE 项目的 SMS 网关。已选择 GAMMU 1.36.0。

后端数据库是 Postgresql 9.4,创建表收件箱和序列来保存短信。

使用创建的收件箱:

CREATE TABLE inbox (
"UpdatedInDB" timestamp(0) WITHOUT time zone NOT NULL DEFAULT     LOCALTIMESTAMP(0),
"ReceivingDateTime" timestamp(0) WITHOUT time zone NOT NULL DEFAULT LOCALTIMESTAMP(0),
"Text" text NOT NULL,
"SenderNumber" varchar(20) NOT NULL DEFAULT '',
"Coding" varchar(255) NOT NULL DEFAULT 'Default_No_Compression',
"UDH" text NOT NULL,
"SMSCNumber" varchar(20) NOT NULL DEFAULT '',
"Class" integer NOT NULL DEFAULT '-1',
"TextDecoded" text NOT NULL DEFAULT '',
"ID" serial PRIMARY KEY,
"RecipientID" text NOT NULL,
"Processed" boolean NOT NULL DEFAULT 'false',
CHECK ("Coding" IN 
  ('Default_No_Compression','Unicode_No_Compression','8bit','Default_Compression','Unicode_Compression')));

id 是一个序列号保存在:

--CREATE SEQUENCE inbox_ID_seq;

表结构如下:

smsd-> \d inbox
                                            Table "public.inbox"
  Column       |              Type              |                           Modifiers                            
-------------------+--------------------------------+----------------------------------------------------------------
UpdatedInDB       | timestamp(0) without time zone | not null default ('now'::text)::timestamp(0) without time zone
ReceivingDateTime | timestamp(0) without time zone | not null default ('now'::text)::timestamp(0) without time zone
Text              | text                           | not null
SenderNumber      | character varying(20)          | not null default ''::character varying
Coding            | character varying(255)         | not null default 'Default_No_Compression'::character varying
UDH               | text                           | not null
SMSCNumber        | character varying(20)          | not null default ''::character varying
Class             | integer                        | not null default (-1)
TextDecoded       | text                           | not null default ''::text
ID                | integer                        | not null default nextval('"inbox_ID_seq"'::regclass)
RecipientID       | text                           | not null
Processed         | boolean                        | not null default false
Indexes:
"inbox_pkey" PRIMARY KEY, btree ("ID")
Check constraints:
"inbox_Coding_check" CHECK ("Coding"::text = ANY (ARRAY['Default_No_Compression'::character varying, 'Unicode_No_Compression'::character varying, '8bit'::character varying, 'Default_Compression'::character varying, 'Unicode_Compression'::character varying]::text[]))
Triggers:
update_timestamp BEFORE UPDATE ON inbox FOR EACH ROW EXECUTE PROCEDURE update_timestamp()

smsd-> 

请注意:列 ids 在表格中的位置是 10。

此表在 GAMMU 1.36.0 上运行良好,发送和接收短信正常。

当我尝试开发 EJB 以将收件箱信息带到我的 Web 应用程序时。

我使用的是 JPA 2.1,实现是 EclipseLink 2.5.2。 persistence.xml 看起来像:

<persistence-unit name="SmsdJPANBPU" transaction-type="RESOURCE_LOCAL">
       <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <mapping-file>com/longz/smsd/model/SmsdInboxEntity.xml</mapping-file>
    <mapping-file>com/longz/smsd/model/SmsdOutboxEntity.xml</mapping-file>
    <mapping-file>com/longz/smsd/model/SmsdSentitemsEntity.xml</mapping-file>
    <class>com.longz.smsd.model.SmsdInboxEntity</class>
    <class>com.longz.smsd.model.SmsdOutboxEntity</class>
    <class>com.longz.smsd.model.SmsdSentitemsEntity</class>
    <properties>
        <property name="eclipselink.jdbc.url" value="jdbc:postgresql://10.0.1.100:5433/smsd"/>
        <property name="eclipselink.jdbc.driver" value="org.postgresql.Driver"/>
        <property name="eclipselink.jdbc.user" value="any"/>
        <property name="eclipselink.jdbc.password" value="any"/>
        <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
    </properties>
</persistence-unit>

JPA 实体 bean 定义:

@Entity
@Table(name = "inbox", schema = "public", catalog = "smsd")
@NamedQueries({
    /*@NamedQuery(name = "Inbox.findAll", query = "SELECT i FROM InboxEntity i ORDER BY i.id DESC"),*/
    @NamedQuery(name = "Inbox.findAll", query = "SELECT i FROM SmsdInboxEntity i order by i.id desc"),
......
public class SmsdInboxEntity implements Serializable{
......
@Id
@SequenceGenerator(name="JOB_MISFIRE_ID_GENERATOR", sequenceName="inbox_ID_seq",schema = "public", allocationSize=1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="JOB_MISFIRE_ID_GENERATOR")
@Column(name = "ID", nullable = false, insertable = true, updatable = true)
public int getId() {
    return id;
}
......
}

无状态会话 bean 为:

@Remote(InboxEntityFacadeRemote.class)
@Stateless(mappedName= "inboxEntityFacadeEJB")
public class InboxEntityFacade extends AbstractFacade<SmsdInboxEntity> implements InboxEntityFacadeRemote {
@PersistenceContext(unitName = "SmsdJPANBPU")
private EntityManager em;

@Override
protected EntityManager getEntityManager() {
    return em;
}

public InboxEntityFacade() {
    super(SmsdInboxEntity.class);
}
@Override
public List<SmsdInboxEntity> findAll(){
    Query query = em.createNamedQuery("Inbox.findAll");
    return new LinkedList<SmsdInboxEntity>(query.getResultList());
    /*return super.findAll();*/
}

我尝试使用 findall() 函数列出收件箱中的所有短信。该函数将调用命名查询语句:

@NamedQuery(name = "Inbox.findAll", query = "SELECT i FROM SmsdInboxEntity i order by i.id desc"),

测试 EJB 客户端为:

try {
        Context context = new InitialContext(properties);
        InboxEntityFacadeRemote inboxEnFaRemote = (InboxEntityFacadeRemote)context.lookup("inboxEntityFacadeEJB#com.longz.smsd.remote.InboxEntityFacadeRemote");
        System.out.println("inboxEntityFacadeEJB found.");
        List<com.longz.smsd.model.SmsdInboxEntity> todaysemails = inboxEnFaRemote.findAll();
        System.out.println("Records found: "+ todaysemails.size());
        todaysemails.stream().forEach((e) -> {
            System.out.println(e.getTextDecoded());
        });

    }catch (NamingException e) {
        e.printStackTrace();
    }

}

到目前为止一切正常。但抛出了非常奇怪的错误:

run:
inboxEntityFacadeEJB found.
Exception in thread "main" javax.ejb.EJBException: EJB Exception: ; nested exception is: 
javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: column "id" does not exist
  Position: 8
  Error Code: 0
Call: SELECT ID, Class, Coding, Processed, ReceivingDateTime, RecipientID, SenderNumber, SMSCNumber, Text, TextDecoded, UDH, UpdatedInDB FROM smsd.public.inbox ORDER BY ID DESC
Query: ReadAllQuery(name="Inbox.findAll" referenceClass=SmsdInboxEntity sql="SELECT ID, Class, Coding, Processed, ReceivingDateTime, RecipientID, SenderNumber, SMSCNumber, Text, TextDecoded, UDH, UpdatedInDB FROM smsd.public.inbox ORDER BY ID DESC")
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.unwrapRemoteException(RemoteBusinessIntfProxy.java:117)
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:92)
at com.sun.proxy.$Proxy0.findAll(Unknown Source)
at weblogicejbclient.WeblogicInboxEJBClient.main(WeblogicInboxEJBClient.java:38)
Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: column "id" does not exist
  Position: 8
  Error Code: 0
Call: SELECT ID, Class, Coding, Processed, ReceivingDateTime, RecipientID, SenderNumber, SMSCNumber, Text, TextDecoded, UDH, UpdatedInDB FROM smsd.public.inbox ORDER BY ID DESC
Query: ReadAllQuery(name="Inbox.findAll" referenceClass=SmsdInboxEntity sql="SELECT ID, Class, Coding, Processed, ReceivingDateTime, RecipientID, SenderNumber, SMSCNumber, Text, TextDecoded, UDH, UpdatedInDB FROM smsd.public.inbox ORDER BY ID DESC")
at org.eclipse.persistence.internal.jpa.QueryImpl.getDetailedException(QueryImpl.java:378)
at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:260)
at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:469)
at com.longz.smsd.ejb.InboxEntityFacade.findAll(InboxEntityFacade.java:36)
at com.longz.smsd.ejb.InboxEntityFacadeEJB_s9wt3_InboxEntityFacadeRemoteImpl.__WL_invoke(Unknown Source)
at weblogic.ejb.container.internal.SessionRemoteMethodInvoker.invoke(SessionRemoteMethodInvoker.java:34)
at com.longz.smsd.ejb.InboxEntityFacadeEJB_s9wt3_InboxEntityFacadeRemoteImpl.findAll(Unknown Source)
at com.longz.smsd.ejb.InboxEntityFacadeEJB_s9wt3_InboxEntityFacadeRemoteImpl_WLSkel.invoke(Unknown Source)
at weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:701)
at weblogic.rmi.cluster.ClusterableServerRef.invoke(ClusterableServerRef.java:231)
at weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:527)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
at weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:523)
at weblogic.rmi.internal.wls.WLSExecuteRequest.run(WLSExecuteRequest.java:118)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: column "id" does not exist
  Position: 8
  Error Code: 0
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:340)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:682)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2002)
at org.eclipse.persistence.sessions.server.ServerSession.executeCall(ServerSession.java:570)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeSelectCall(DatasourceCallQueryMechanism.java:299)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.selectAllRows(DatasourceCallQueryMechanism.java:694)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRowsFromTable(ExpressionQueryMechanism.java:2738)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRows(ExpressionQueryMechanism.java:2691)
at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:495)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1168)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1127)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:403)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1215)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1804)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1786)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1751)
at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:258)
... 15 more
Caused by: org.postgresql.util.PSQLException: ERROR: column "id" does not exist
  Position: 8
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2198)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1927)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:561)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:419)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:304)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeSelect(DatabaseAccessor.java:1007)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:642)
... 35 more
Java Result: 1
BUILD SUCCESSFUL (total time: 1 second)

似乎 PSQL 试图在第 8 位而不是第 10 位找到“id”列,而实际上“id”列位于收件箱表中的第 10 位。

请有任何想法和建议!赞赏!!

【问题讨论】:

    标签: postgresql jpa position sequence identity-column


    【解决方案1】:

    您的问题是区分大小写:JPA works in case insensitive mode 默认情况下(即它不会在其查询中引用标识符),而 PostgreSQL will convert any unquoted identifiers to lower-case(这是 PostgreSQL 尝试实现不区分大小写的方式)。但是,您以区分大小写的模式定义了 "ID" 列(注意引号)。

    一个丑陋的解决方法是,您以区分大小写的方式定义您的实体:

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

    或者,您可以以不区分大小写的方式定义您的表(这是首选):

    CREATE TABLE inbox (
        ID serial PRIMARY KEY
        -- ...
    );
    

    【讨论】:

    • 非常感谢!似乎这项工作对我有用。不幸的是,我无法重新定义 DB 模式,因为 C++ 需要使用它,它必须保持原样。再次感谢您。
    • 感谢您的回复和建议。我刚刚测试了它,但它不是一直有效。
    【解决方案2】:

    最终。此问题已通过使用本机 SQL 查询修复

    Query query = em.createNativeQuery("Select * from inbox",com.longz.smsd.model.SmsdInboxEntity.class);
    return new LinkedList<SmsdInboxEntity>(query.getResultList());
    

    似乎 JSQL 在这种情况下不是 100% 有效。

    这个可以帮助遇到同样问题的其他人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-13
      • 2011-09-15
      • 2017-09-21
      • 1970-01-01
      • 1970-01-01
      • 2015-02-27
      • 2014-07-06
      • 1970-01-01
      相关资源
      最近更新 更多